Skip to content

Commit b262b17

Browse files
author
Patrick Palka
committed
c++: build_extra_args recapturing local specs [PR114303]
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 which we'll now walk first. 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 (tree_extra_args): Define. (extract_locals_r): Assert *_EXTRA_ARGS is empty. (tsubst_stmt) <case IF_STMT>: Clear IF_SCOPE on the new 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. Reviewed-by: Jason Merrill <[email protected]>
1 parent 0dc39de commit b262b17

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

gcc/cp/constraint.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,6 +2362,7 @@ tsubst_requires_expr (tree t, tree args, sat_info info)
23622362
matching or dguide constraint rewriting), in which case we need
23632363
to partially substitute. */
23642364
t = copy_node (t);
2365+
REQUIRES_EXPR_EXTRA_ARGS (t) = NULL_TREE;
23652366
REQUIRES_EXPR_EXTRA_ARGS (t) = build_extra_args (t, args, info.complain);
23662367
return t;
23672368
}

gcc/cp/pt.cc

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3858,6 +3858,24 @@ has_extra_args_mechanism_p (const_tree t)
38583858
&& IF_STMT_CONSTEXPR_P (t))); /* IF_STMT_EXTRA_ARGS */
38593859
}
38603860

3861+
/* Return *_EXTRA_ARGS of the given supported tree T. */
3862+
3863+
static tree&
3864+
tree_extra_args (tree t)
3865+
{
3866+
gcc_checking_assert (has_extra_args_mechanism_p (t));
3867+
3868+
if (PACK_EXPANSION_P (t))
3869+
return PACK_EXPANSION_EXTRA_ARGS (t);
3870+
else if (TREE_CODE (t) == REQUIRES_EXPR)
3871+
return REQUIRES_EXPR_EXTRA_ARGS (t);
3872+
else if (TREE_CODE (t) == IF_STMT
3873+
&& IF_STMT_CONSTEXPR_P (t))
3874+
return IF_STMT_EXTRA_ARGS (t);
3875+
3876+
gcc_unreachable ();
3877+
}
3878+
38613879
/* Structure used to track the progress of find_parameter_packs_r. */
38623880
struct find_parameter_pack_data
38633881
{
@@ -13291,6 +13309,16 @@ extract_locals_r (tree *tp, int *walk_subtrees, void *data_)
1329113309
/* Remember local typedefs (85214). */
1329213310
tp = &TYPE_NAME (*tp);
1329313311

13312+
if (has_extra_args_mechanism_p (*tp))
13313+
/* Assert *_EXTRA_ARGS is empty, because we don't want to walk it and
13314+
potentially see a previously captured local in an evaluated context
13315+
that's really only used in an unevaluated context (PR114303). This
13316+
means callers of build_extra_args need to clear *_EXTRA_ARGS of the
13317+
outermost tree. Nested *_EXTRA_ARGS should naturally be empty since
13318+
the outermost (extra-args) tree will intercept any substitution before
13319+
a nested tree can. */
13320+
gcc_checking_assert (tree_extra_args (*tp) == NULL_TREE);
13321+
1329413322
if (TREE_CODE (*tp) == DECL_EXPR)
1329513323
{
1329613324
tree decl = DECL_EXPR_DECL (*tp);
@@ -18716,10 +18744,11 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t complain, tree in_decl)
1871618744
of the constexpr if is still dependent. Don't substitute into the
1871718745
branches now, just remember the template arguments. */
1871818746
do_poplevel (IF_SCOPE (stmt));
18747+
IF_SCOPE (stmt) = NULL_TREE;
1871918748
IF_COND (stmt) = IF_COND (t);
1872018749
THEN_CLAUSE (stmt) = THEN_CLAUSE (t);
1872118750
ELSE_CLAUSE (stmt) = ELSE_CLAUSE (t);
18722-
IF_STMT_EXTRA_ARGS (stmt) = build_extra_args (t, args, complain);
18751+
IF_STMT_EXTRA_ARGS (stmt) = build_extra_args (stmt, args, complain);
1872318752
add_stmt (stmt);
1872418753
break;
1872518754
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// PR c++/114303
2+
// { dg-do compile { target c++17 } }
3+
4+
struct A { static constexpr bool value = true; };
5+
6+
int main() {
7+
[](auto x1) {
8+
return [&](auto) {
9+
return [&](auto x3) {
10+
if constexpr (decltype(x3)::value) {
11+
static_assert(decltype(x1)::value);
12+
}
13+
}(A{});
14+
}(0);
15+
}(A{});
16+
}

0 commit comments

Comments
 (0)