https://gcc.gnu.org/g:00966a7fdb1478b3af5254ff3a80a3ef336c5a94

commit r15-9433-g00966a7fdb1478b3af5254ff3a80a3ef336c5a94
Author: Patrick Palka <ppa...@redhat.com>
Date:   Mon Apr 14 11:20:13 2025 -0400

    c++: wrong targs in satisfaction diagnostic context line [PR99214]
    
    In the three-parameter version of satisfy_declaration_constraints, when
    't' isn't the most general template, then 't' won't correspond with
    'args' after we augment the latter via add_outermost_template_args, and
    so the instantiation context that we push via push_tinst_level isn't
    quite correct: 'args' is a complete set of template arguments, but 't'
    is not necessarily the most general template.  This manifests as
    misleading diagnostic context lines when issuing a satisfaction failure
    error, e.g.  the below testcase without this patch we emit:
      In substitution of '... void A<int>::f<U>() ... [with U = int]'
    and with this patch we emit:
      In substitution of '... void A<int>::f<U>() ... [with U = char]'.
    
    This patch fixes this by passing the original 'args' to push_tinst_level,
    which ought to properly correspond to 't'.
    
            PR c++/99214
    
    gcc/cp/ChangeLog:
    
            * constraint.cc (satisfy_declaration_constraints): Pass the
            original ARGS to push_tinst_level.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/concepts/diagnostic20.C: New test.
    
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Diff:
---
 gcc/cp/constraint.cc                         |  4 +++-
 gcc/testsuite/g++.dg/concepts/diagnostic20.C | 13 +++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 2f1678ce4ff9..44fb086c6306 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -2704,6 +2704,8 @@ satisfy_declaration_constraints (tree t, sat_info info)
 static tree
 satisfy_declaration_constraints (tree t, tree args, sat_info info)
 {
+  tree orig_args = args;
+
   /* Update the declaration for diagnostics.  */
   info.in_decl = t;
 
@@ -2732,7 +2734,7 @@ satisfy_declaration_constraints (tree t, tree args, 
sat_info info)
   tree result = boolean_true_node;
   if (tree norm = get_normalized_constraints_from_decl (t, info.noisy ()))
     {
-      if (!push_tinst_level (t, args))
+      if (!push_tinst_level (t, orig_args))
        return result;
       tree pattern = DECL_TEMPLATE_RESULT (t);
       push_to_top_level ();
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic20.C 
b/gcc/testsuite/g++.dg/concepts/diagnostic20.C
new file mode 100644
index 000000000000..2bb01db44dec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic20.C
@@ -0,0 +1,13 @@
+// PR c++/99214
+// { dg-do compile { target c++20 } }
+
+template <class T>
+struct A {
+  template <class U> static void f() requires requires { T::fail; };
+};
+
+int main() {
+  A<int>::f<char>(); // { dg-error "no match" }
+}
+
+// { dg-message "In substitution of '\[^\r\n\]* \\\[with U = char\\\]'" "" { 
target *-*-* } 0 }

Reply via email to