From 30c286aa9377850c64aa35f5845a59d321a44be0 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Sun, 19 Dec 2021 12:10:16 -0500 Subject: [PATCH] c++: local_specializations and recursive constrained fn [PR103714] Here during constraint checking for the inner call to A<0>::f<0>, substitution into the PARM_DECL d in the atomic constraint yields the wrong local specialization because local_specializations at this point is nonempty, and contains specializations for the caller A<0>::f<1>. This patch makes us call push_to_top_level during satisfaction, which'll temporarily clear local_specializations for us. PR c++/103714 gcc/cp/ChangeLog: * constraint.cc (satisfy_declaration_constraints): Do push_to_top_level and pop_from_top_level around the call to satisfy_normalized_constraints. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-uneval5.C: New test. --- gcc/cp/constraint.cc | 4 ++++ gcc/testsuite/g++.dg/cpp2a/concepts-uneval5.C | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-uneval5.C diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 8386a7d..96fa6a7 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3177,9 +3177,11 @@ satisfy_declaration_constraints (tree t, sat_info info) { if (!push_tinst_level (t)) return result; + push_to_top_level (); push_access_scope (t); result = satisfy_normalized_constraints (norm, args, info); pop_access_scope (t); + pop_from_top_level (); pop_tinst_level (); } @@ -3235,9 +3237,11 @@ satisfy_declaration_constraints (tree t, tree args, sat_info info) if (!push_tinst_level (t, args)) return result; tree pattern = DECL_TEMPLATE_RESULT (t); + push_to_top_level (); push_access_scope (pattern); result = satisfy_normalized_constraints (norm, args, info); pop_access_scope (pattern); + pop_from_top_level (); pop_tinst_level (); } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-uneval5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-uneval5.C new file mode 100644 index 0000000..a315a59 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-uneval5.C @@ -0,0 +1,17 @@ +// PR c++/103714 +// { dg-do compile { target c++20 } } + +template +struct A { + static const int i = I; + + template + void f(A d = {}) requires (d.i != i) { + f(); // { dg-error "no match" } + } +}; + +int main() { + A<0> a; + a.f<1>(); +} -- 2.7.4