On Tue, 12 Mar 2024, Patrick Palka wrote: > On Tue, 12 Mar 2024, Jason Merrill wrote: > > > On 3/11/24 12:53, Patrick Palka wrote: > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look > > > OK for trunk and release branches? > > > > > > -- >8 -- > > > > > > r13-6452-g341e6cd8d603a3 made build_extra_args walk evaluated contexts > > > first so that we prefer processing a local specialization in an evaluated > > > context even if its first use is in an unevaluated context. But this > > > means we need to avoid walking a tree that already has extra args/specs > > > saved because the list of saved specs appears to be an evaluated > > > context. It seems then that we should be calculating the saved specs > > > from scratch each time, rather than potentially walking the saved specs > > > list from an earlier partial instantiation when calling build_extra_args > > > a second time around. > > > > Makes sense, but I wonder if we want to approach that by avoiding walking > > into > > *_EXTRA_ARGS in extract_locals_r? Or do we still want to walk into any > > nested > > extra args? And if so, will we run into this same problem then? > > I'm not sure totally but I'd expect a nested extra-args tree to always > have empty *_EXTRA_ARGS since the outer extra-args tree should intercept > any substitution before the inner extra-args tree can see it?
... and so in extract_locals_r I think we can assume *_EXTRA_ARGS is empty, and not have to explicitly avoid walking it. > > > > > > PR c++/114303 > > > > > > gcc/cp/ChangeLog: > > > > > > * constraint.cc (tsubst_requires_expr): Clear > > > REQUIRES_EXPR_EXTRA_ARGS before calling build_extra_args. > > > * pt.cc (tsubst_stmt) <case IF_STMT>: Call build_extra_args > > > on the new IF_STMT instead of t which might already have > > > IF_STMT_EXTRA_ARGS. > > > > > > gcc/testsuite/ChangeLog: > > > > > > * g++.dg/cpp1z/constexpr-if-lambda6.C: New test. > > > --- > > > gcc/cp/constraint.cc | 1 + > > > gcc/cp/pt.cc | 2 +- > > > .../g++.dg/cpp1z/constexpr-if-lambda6.C | 16 ++++++++++++++++ > > > 3 files changed, 18 insertions(+), 1 deletion(-) > > > create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda6.C > > > > > > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc > > > index 49de3211d4c..8a3b5d80ba7 100644 > > > --- a/gcc/cp/constraint.cc > > > +++ b/gcc/cp/constraint.cc > > > @@ -2362,6 +2362,7 @@ tsubst_requires_expr (tree t, tree args, sat_info > > > info) > > > matching or dguide constraint rewriting), in which case we need > > > to partially substitute. */ > > > t = copy_node (t); > > > + REQUIRES_EXPR_EXTRA_ARGS (t) = NULL_TREE; > > > REQUIRES_EXPR_EXTRA_ARGS (t) = build_extra_args (t, args, > > > info.complain); > > > return t; > > > } > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > > > index 8cf0d5b7a8d..37f2392d035 100644 > > > --- a/gcc/cp/pt.cc > > > +++ b/gcc/cp/pt.cc > > > @@ -18718,7 +18718,7 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t > > > complain, tree in_decl) > > > IF_COND (stmt) = IF_COND (t); > > > THEN_CLAUSE (stmt) = THEN_CLAUSE (t); > > > ELSE_CLAUSE (stmt) = ELSE_CLAUSE (t); > > > - IF_STMT_EXTRA_ARGS (stmt) = build_extra_args (t, args, complain); > > > + IF_STMT_EXTRA_ARGS (stmt) = build_extra_args (stmt, args, complain); > > > add_stmt (stmt); > > > break; > > > } > > > diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda6.C > > > b/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda6.C > > > new file mode 100644 > > > index 00000000000..038c2a41210 > > > --- /dev/null > > > +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda6.C > > > @@ -0,0 +1,16 @@ > > > +// PR c++/114303 > > > +// { dg-do compile { target c++17 } } > > > + > > > +struct A { static constexpr bool value = true; }; > > > + > > > +int main() { > > > + [](auto x1) { > > > + return [&](auto) { > > > + return [&](auto x3) { > > > + if constexpr (decltype(x3)::value) { > > > + static_assert(decltype(x1)::value); > > > + } > > > + }(A{}); > > > + }(0); > > > + }(A{}); > > > +} > > > > >