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?
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{});
+}