semantics.c (constexpr_fn_retval): Ignore declarations in C++14.

* semantics.c (constexpr_fn_retval): Ignore declarations in C++14.
	(var_in_constexpr_fn): New.
	(cxx_eval_constant_expression): Look into DECL_INITIAL.
	(potential_constant_expression_1): Allow constexpr-local vars.

From-SVN: r215862
This commit is contained in:
Jason Merrill 2014-10-03 12:48:18 -04:00 committed by Jason Merrill
parent 742a072ad0
commit e01a49c11b
4 changed files with 31 additions and 0 deletions

View File

@ -1,5 +1,10 @@
2014-10-03 Jason Merrill <jason@redhat.com>
* semantics.c (constexpr_fn_retval): Ignore declarations in C++14.
(var_in_constexpr_fn): New.
(cxx_eval_constant_expression): Look into DECL_INITIAL.
(potential_constant_expression_1): Allow constexpr-local vars.
PR c++/63362
* tree.c (strip_typedefs): Handle TREE_LIST.

View File

@ -5833,6 +5833,7 @@ extern tree maybe_constant_value (tree);
extern tree maybe_constant_init (tree);
extern bool is_sub_constant_expr (tree);
extern bool reduced_constant_expression_p (tree);
extern bool var_in_constexpr_fn (tree);
extern void explain_invalid_constexpr_fn (tree);
extern vec<tree> cx_error_context (void);
extern bool is_this_parameter (tree);

View File

@ -8018,6 +8018,8 @@ constexpr_fn_retval (tree body)
case DECL_EXPR:
if (TREE_CODE (DECL_EXPR_DECL (body)) == USING_DECL)
return NULL_TREE;
if (cxx_dialect >= cxx14)
return NULL_TREE;
return error_mark_node;
case CLEANUP_POINT_EXPR:
@ -9596,6 +9598,14 @@ cxx_eval_trinary_expression (const constexpr_call *call, tree t,
return val;
}
bool
var_in_constexpr_fn (tree t)
{
tree ctx = DECL_CONTEXT (t);
return (cxx_dialect >= cxx14 && ctx && TREE_CODE (ctx) == FUNCTION_DECL
&& DECL_DECLARED_CONSTEXPR_P (ctx));
}
/* Attempt to reduce the expression T to a constant value.
On failure, issue diagnostic and return error_mark_node. */
/* FIXME unify with c_fully_fold */
@ -9635,6 +9645,11 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
if (TREE_CODE (r) == TARGET_EXPR
&& TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
r = TARGET_EXPR_INITIAL (r);
if (DECL_P (r) && var_in_constexpr_fn (r)
&& DECL_INITIAL (r))
r = cxx_eval_constant_expression (call, DECL_INITIAL (r),
allow_non_constant, false,
non_constant_p, overflow_p);
if (DECL_P (r))
{
if (!allow_non_constant)
@ -10320,6 +10335,7 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
case VAR_DECL:
if (want_rval && !decl_constant_var_p (t)
&& !var_in_constexpr_fn (t)
&& !dependent_type_p (TREE_TYPE (t)))
{
if (flags & tf_error)

View File

@ -0,0 +1,9 @@
// { dg-do compile { target c++14 } }
constexpr int f(int i) { int j = i+1; return j; }
constexpr int i = f(41);
#define SA(X) static_assert((X),#X)
SA(i==42);