c++: Constant expression parsing and parameters.
authorJason Merrill <jason@redhat.com>
Thu, 21 May 2020 14:27:11 +0000 (10:27 -0400)
committerJason Merrill <jason@redhat.com>
Thu, 21 May 2020 22:04:22 +0000 (18:04 -0400)
The difference between a "potential" constant-expression and a regular
constant-expression is the treatment of parameters; in a constexpr function,
a parameter is potentially constant when evaluating a call to that function,
but it is not constant during parsing of the function.
cp_parser_constant_expression should check the latter rather than the
former.

gcc/cp/ChangeLog:

* cp-tree.h (is_rvalue_constant_expression): Declare.
* constexpr.c (is_rvalue_constant_expression): New.
* parser.c (cp_parser_constant_expression): Use it.
* decl.c (cp_finish_decl): Try to treat a constexpr initializer in a
template as constant.

gcc/cp/constexpr.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/parser.c

index c1ab928..98c974e 100644 (file)
@@ -8359,6 +8359,14 @@ is_constant_expression (tree t)
   return potential_constant_expression_1 (t, false, true, true, tf_none);
 }
 
+/* As above, but expect an rvalue.  */
+
+bool
+is_rvalue_constant_expression (tree t)
+{
+  return potential_constant_expression_1 (t, true, true, true, tf_none);
+}
+
 /* Like above, but complain about non-constant expressions.  */
 
 bool
index 07c1614..db125a3 100644 (file)
@@ -7939,6 +7939,7 @@ extern tree constexpr_fn_retval           (tree);
 extern tree ensure_literal_type_for_constexpr_object (tree);
 extern bool potential_constant_expression       (tree);
 extern bool is_constant_expression (tree);
+extern bool is_rvalue_constant_expression (tree);
 extern bool is_nondependent_constant_expression (tree);
 extern bool is_nondependent_static_init_expression (tree);
 extern bool is_static_init_expression    (tree);
index a389579..6d1c08e 100644 (file)
@@ -7612,7 +7612,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
          init = boolean_true_node;
        }
       else if (init
-              && init_const_expr_p
+              && (init_const_expr_p || DECL_DECLARED_CONSTEXPR_P (decl))
               && !TYPE_REF_P (type)
               && decl_maybe_constant_var_p (decl)
               && !(dep_init = value_dependent_init_p (init)))
index a8082d3..6a0ef4d 100644 (file)
@@ -10184,10 +10184,10 @@ cp_parser_constant_expression (cp_parser* parser,
       if (TREE_TYPE (expression)
          && TREE_CODE (TREE_TYPE (expression)) == ARRAY_TYPE)
        decay = build_address (expression);
-      bool is_const = potential_rvalue_constant_expression (decay);
+      bool is_const = is_rvalue_constant_expression (decay);
       parser->non_integral_constant_expression_p = !is_const;
       if (!is_const && !allow_non_constant_p)
-       require_potential_rvalue_constant_expression (decay);
+       require_rvalue_constant_expression (decay);
     }
   if (allow_non_constant_p)
     *non_constant_p = parser->non_integral_constant_expression_p;