From e01a49c11b529db0a092c9af935141730a9269ed Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 3 Oct 2014 12:48:18 -0400 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/cp-tree.h | 1 + gcc/cp/semantics.c | 16 ++++++++++++++++ gcc/testsuite/g++.dg/cpp1y/constexpr-local1.C | 9 +++++++++ 4 files changed, 31 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-local1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4f91a68824b..56c3bdbd51b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2014-10-03 Jason Merrill + * 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. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index fe1651ef010..857af769f2b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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 cx_error_context (void); extern bool is_this_parameter (tree); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 756982667b1..6c6a5c88214 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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) diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-local1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-local1.C new file mode 100644 index 00000000000..39c3ee84de5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-local1.C @@ -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);