On 2/25/21 1:37 AM, Patrick Palka wrote:
In-Reply-To: <20210225063712.3725111-1-ppa...@redhat.com>
BTW, This patch doesn't seem in any way a reply to your previous patch,
so it's confusing for the mail headers (and thus MUA threading) to say
that it is. Maybe you want git send-email --no-thread or
git config sendemail.thread false ?
In the three-parameter version of satisfy_declaration_constraints, when
't' isn't the most general template, then 't' doesn't correspond with
the augmented template arguments 'args', and so the instantiation
context that we push via push_tinst_level isn't quite correct. This
manifests as misleading diagnostic context lines during satisfaction
failure as in the testcase below for which without this patch we emit
In substitution of '... static void A<int>::f<U>() [with U = int]'
and with this patch we emit
In substitution of '... static void A<T>::f<U>() [with U = char; T = int]'.
This patch fixes this by passing the most general template to
push_tinst_level.
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?
gcc/cp/ChangeLog:
PR c++/99214
* constraint.cc (get_normalized_constraints_from_decl): Fix
formatting.
(satisfy_declaration_constraints): Be lazy about augmenting
'args'. Pass the most general template to push_tinst_level.
gcc/testsuite/ChangeLog:
PR c++/99214
* g++.dg/concepts/diagnostic16.C: New test.
---
gcc/cp/constraint.cc | 16 ++++++++--------
gcc/testsuite/g++.dg/concepts/diagnostic16.C | 15 +++++++++++++++
2 files changed, 23 insertions(+), 8 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/concepts/diagnostic16.C
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 31e0fb5079a..88963e687a7 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -910,11 +910,9 @@ get_normalized_constraints_from_decl (tree d, bool diag =
false)
accepting the latter causes the template parameter level of U
to be reduced in a way that makes it overly difficult substitute
concrete arguments (i.e., eventually {int, int} during satisfaction. */
- if (tmpl)
- {
- if (DECL_LANG_SPECIFIC(tmpl) && !DECL_TEMPLATE_SPECIALIZATION (tmpl))
- tmpl = most_general_template (tmpl);
- }
+ if (tmpl && DECL_LANG_SPECIFIC (tmpl)
+ && !DECL_TEMPLATE_SPECIALIZATION (tmpl))
+ tmpl = most_general_template (tmpl);
Can we use template_for_substitution instead of checking
DECL_TEMPLATE_SPECIALIZATION and most_general_template? That seems to
be the semantic we want.
/* If we're not diagnosing errors, use cached constraints, if any. */
if (!diag)
@@ -3157,12 +3155,14 @@ satisfy_declaration_constraints (tree t, tree args,
sat_info info)
gcc_assert (TREE_CODE (t) == TEMPLATE_DECL);
- args = add_outermost_template_args (t, args);
-
tree result = boolean_true_node;
if (tree norm = normalize_template_requirements (t, info.noisy ()))
{
- if (!push_tinst_level (t, args))
+ args = add_outermost_template_args (t, args);
+ tree gen_tmpl = t;
+ if (DECL_LANG_SPECIFIC (t) && !DECL_TEMPLATE_SPECIALIZATION (t))
+ gen_tmpl = most_general_template (t);
+ if (!push_tinst_level (gen_tmpl, args))
return result;
tree pattern = DECL_TEMPLATE_RESULT (t);
push_access_scope (pattern);
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic16.C
b/gcc/testsuite/g++.dg/concepts/diagnostic16.C
new file mode 100644
index 00000000000..b8d586e9a21
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic16.C
@@ -0,0 +1,15 @@
+// PR c++/99214
+// { dg-do compile { target c++20 } }
+
+template <class T>
+struct A {
+ template <class U> static void f() requires ([] { return U::fail; }()); // { dg-error
"fail" }
+ template <class U> static void f();
+};
+
+int main() {
+ A<int>::f<char>();
+}
+
+// This matches the context line "In substitution of '... [with U = char; T =
int]'"
+// { dg-message "U = char; T = int" "" { target *-*-* } 0 }