On 2/20/26 2:49 AM, Marek Polacek wrote:
dg.exp=reflect/* passed on x86_64-linux so far.  Ok for trunk?

-- >8 --
As discussed in
<https://gcc.gnu.org/pipermail/gcc-patches/2026-January/705756.html>,
we shouldn't walk BIND_EXPR_VARS in check_out_of_consteval_use_r, but
BIND_EXPR_BODY should still be walked.

The IF_STMT is there so that we don't emit bogus errors in "if consteval"
branches, as tested in expr12.C.

gcc/cp/ChangeLog:

        * reflect.cc (check_out_of_consteval_use_r): Walk BIND_EXPR_BODY.
        For IF_STMT_CONSTEVAL_P, only walk the ELSE_CLAUSE.

gcc/testsuite/ChangeLog:

        * g++.dg/reflect/expr11.C: Adjust dg-error.
        * g++.dg/reflect/expr12.C: Adjust test.
---
  gcc/cp/reflect.cc                     | 24 ++++++++++++++++++++++--
  gcc/testsuite/g++.dg/reflect/expr11.C |  2 +-
  gcc/testsuite/g++.dg/reflect/expr12.C | 18 ++++++++++++++++++
  3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index 46355251bcd..0e9118129be 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -8108,8 +8108,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)
      {
@@ -8139,6 +8137,28 @@ 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<hash_set<tree> *>(pset)))
+       return r;
+      /* Don't walk BIND_EXPR_VARS.  */
+      *walk_subtrees = false;
+      return NULL_TREE;
+    }
+
+  if (TREE_CODE (t) == IF_STMT && IF_STMT_CONSTEVAL_P (t))
+    {
+      if (tree r = cp_walk_tree (&ELSE_CLAUSE (t),
+                                check_out_of_consteval_use_r, pset,
+                                static_cast<hash_set<tree> *>(pset)))
+       return r;
+      /* Don't walk the consteval branch.  */
+      *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..9691ceb07c7 100644
--- a/gcc/testsuite/g++.dg/reflect/expr11.C
+++ b/gcc/testsuite/g++.dg/reflect/expr11.C
@@ -15,7 +15,7 @@ f ()
        constexpr auto cr = ^^int;
      }
    if constexpr (auto r = ^^int;  // { dg-error "consteval-only variable .r." }
-               r == ^^int);     // { dg-error "the value of .r. is not usable" 
}
+               r == ^^int);     // { dg-error "consteval-only expressions|the value 
of .r. is not usable" }

This change seems wrong, since the condition of an "if constexpr" is manifestly constant-evaluated.

Jason

Reply via email to