Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

r11-7740 limited constexpr rejection of conversion from pointer to integer
to manifestly constant-evaluated contexts; it should instead check whether
we're in strict mode.

The comment for that commit noted that making this change regressed other
tests, which turned out to be because maybe_constant_init_1 was not being
properly strict for variables declared constexpr/constinit.

        PR c++/99456

gcc/cp/ChangeLog:

        * constexpr.cc (cxx_eval_constant_expression): Check strict
        instead of manifestly_const_eval.
        (maybe_constant_init_1): Be strict for static constexpr vars.
---
 gcc/cp/constexpr.cc | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index f56c5c42c82..be73e707aaf 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -8479,7 +8479,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
        if (TREE_CODE (t) == CONVERT_EXPR
            && ARITHMETIC_TYPE_P (type)
            && INDIRECT_TYPE_P (TREE_TYPE (op))
-           && ctx->manifestly_const_eval == mce_true)
+           && ctx->strict)
          {
            if (!ctx->quiet)
              error_at (loc,
@@ -9747,16 +9747,26 @@ maybe_constant_init_1 (tree t, tree decl, bool 
allow_non_constant,
     {
       /* [basic.start.static] allows constant-initialization of variables with
         static or thread storage duration even if it isn't required, but we
-        shouldn't bend the rules the same way for automatic variables.  */
+        shouldn't bend the rules the same way for automatic variables.
+
+        But still enforce the requirements of constexpr/constinit.
+        [dcl.constinit] "If a variable declared with the constinit specifier
+        has dynamic initialization, the program is ill-formed, even if the
+        implementation would perform that initialization as a static
+        initialization."  */
       bool is_static = (decl && DECL_P (decl)
                        && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
+      bool strict = (!is_static
+                    || (decl && DECL_P (decl)
+                        && (DECL_DECLARED_CONSTEXPR_P (decl)
+                            || DECL_DECLARED_CONSTINIT_P (decl))));
       if (is_static)
        manifestly_const_eval = mce_true;
 
       if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
        return fold_to_constant (t);
 
-      t = cxx_eval_outermost_constant_expr (t, allow_non_constant, !is_static,
+      t = cxx_eval_outermost_constant_expr (t, allow_non_constant, strict,
                                            manifestly_const_eval,
                                            false, decl);
     }

base-commit: 0907a810f586b07636cc5b83dba6025eb5240655
-- 
2.49.0

Reply via email to