]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: wrong targs in satisfaction diagnostic context line [PR99214]
authorPatrick Palka <ppalka@redhat.com>
Mon, 14 Apr 2025 15:20:13 +0000 (11:20 -0400)
committerPatrick Palka <ppalka@redhat.com>
Mon, 14 Apr 2025 15:20:13 +0000 (11:20 -0400)
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 <jason@redhat.com>
gcc/cp/constraint.cc
gcc/testsuite/g++.dg/concepts/diagnostic20.C [new file with mode: 0644]

index 2f1678ce4ff9cc1fc6a9ae8b513d91a01833f1d7..44fb086c6306d65b18e5f2ae18a5dc3f7641a1ea 100644 (file)
@@ -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 (file)
index 0000000..2bb01db
--- /dev/null
@@ -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 }