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.
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);
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:
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 */
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)
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)
--- /dev/null
+// { 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);