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. 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{}); +} -- 2.44.0.165.ge09f1254c5