diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc index 5254ac028d1..3c82251f511 100644 --- a/gcc/cp/reflect.cc +++ b/gcc/cp/reflect.cc @@ -8120,8 +8120,6 @@ check_out_of_consteval_use_r (tree *tp, int *walk_subtrees, void *pset) /* Don't walk INIT_EXPRs, because we'd emit bogus errors about member initializers. */ || TREE_CODE (t) == INIT_EXPR - /* Don't walk BIND_EXPR_VARS. */ - || TREE_CODE (t) == BIND_EXPR /* And don't recurse on DECL_EXPRs. */ || TREE_CODE (t) == DECL_EXPR) { @@ -8151,6 +8149,46 @@ check_out_of_consteval_use_r (tree *tp, int *walk_subtrees, void *pset) return ret; } + if (TREE_CODE (t) == BIND_EXPR) + { + if (tree r = cp_walk_tree (&BIND_EXPR_BODY (t), + check_out_of_consteval_use_r, pset, + static_cast *>(pset))) + return r; + /* Don't walk BIND_EXPR_VARS. */ + *walk_subtrees = false; + return NULL_TREE; + } + + if (TREE_CODE (t) == IF_STMT) + { + if (IF_STMT_CONSTEVAL_P (t)) + { + if (tree r = cp_walk_tree (&ELSE_CLAUSE (t), + check_out_of_consteval_use_r, pset, + static_cast *>(pset))) + return r; + /* Don't walk the consteval branch. */ + *walk_subtrees = false; + return NULL_TREE; + } + else if (IF_STMT_CONSTEXPR_P (t)) + { + if (tree r = cp_walk_tree (&THEN_CLAUSE (t), + check_out_of_consteval_use_r, pset, + static_cast *>(pset))) + return r; + if (tree r = cp_walk_tree (&ELSE_CLAUSE (t), + check_out_of_consteval_use_r, pset, + static_cast *>(pset))) + return r; + /* Don't walk the condition -- it's a manifestly constant-evaluated + context. */ + *walk_subtrees = false; + return NULL_TREE; + } + } + /* Now check the type to see if we are dealing with a consteval-only expression. */ if (!consteval_only_p (t)) diff --git a/gcc/testsuite/g++.dg/reflect/expr11.C b/gcc/testsuite/g++.dg/reflect/expr11.C index 20af4bc07ae..44d66947d9d 100644 --- a/gcc/testsuite/g++.dg/reflect/expr11.C +++ b/gcc/testsuite/g++.dg/reflect/expr11.C @@ -29,4 +29,21 @@ f () while (^^char != ^^char); do {} while (^^char != ^^char); } + + if constexpr (true) + { + auto r = ^^int; // { dg-error "consteval-only variable .r." } + } + else + { + auto r = ^^int; // { dg-error "consteval-only variable .r." } + } + if constexpr (false) + { + auto r = ^^int; // { dg-error "consteval-only variable .r." } + } + else + { + auto r = ^^int; // { dg-error "consteval-only variable .r." } + } } diff --git a/gcc/testsuite/g++.dg/reflect/expr12.C b/gcc/testsuite/g++.dg/reflect/expr12.C index a59a60f03a3..34aed536429 100644 --- a/gcc/testsuite/g++.dg/reflect/expr12.C +++ b/gcc/testsuite/g++.dg/reflect/expr12.C @@ -20,11 +20,29 @@ f () if not consteval { ^^void; // { dg-error "consteval-only expressions" } + } + if not consteval + { q; // { dg-error "consteval-only expressions" } + } + if not consteval + { auto r = ^^int; // { dg-error "consteval-only variable" } + } + if not consteval + { if (q != ^^char); // { dg-error "consteval-only expressions" } + } + if not consteval + { if (^^char == ^^char); // { dg-error "consteval-only expressions" } + } + if not consteval + { while (^^char != ^^char); // { dg-error "consteval-only expressions" } + } + if not consteval + { do {} while (^^char != ^^char); // { dg-error "consteval-only expressions" } } }