c++: Constant expression parsing and parameters.

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.
This commit is contained in:
Jason Merrill 2020-05-21 10:27:11 -04:00
parent 4f602147b6
commit beb019d346
4 changed files with 12 additions and 3 deletions

View 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

View 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);

View 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)))

View 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;