diff options
author | Patrick Palka <ppalka@redhat.com> | 2025-04-14 11:20:13 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2025-04-14 11:20:13 -0400 |
commit | 00966a7fdb1478b3af5254ff3a80a3ef336c5a94 (patch) | |
tree | b5b28cc4942e9c30053912c03f563e045e4991fa /gcc | |
parent | 6518799b2dfe8cf6dd7afa96041c5842bb4b9a49 (diff) | |
download | gcc-00966a7fdb1478b3af5254ff3a80a3ef336c5a94.zip gcc-00966a7fdb1478b3af5254ff3a80a3ef336c5a94.tar.gz gcc-00966a7fdb1478b3af5254ff3a80a3ef336c5a94.tar.bz2 |
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 <jason@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/constraint.cc | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/concepts/diagnostic20.C | 13 |
2 files changed, 16 insertions, 1 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 2f1678c..44fb086 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 0000000..2bb01db --- /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 } |