aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-10-03 12:48:18 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-10-03 12:48:18 -0400
commite01a49c11b529db0a092c9af935141730a9269ed (patch)
treef9c5ac1661c6d266beda46347940f70f13f9f860 /gcc
parent742a072ad0e351dbe5b483002142c8215597d386 (diff)
downloadgcc-e01a49c11b529db0a092c9af935141730a9269ed.zip
gcc-e01a49c11b529db0a092c9af935141730a9269ed.tar.gz
gcc-e01a49c11b529db0a092c9af935141730a9269ed.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/semantics.c16
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-local1.C9
4 files changed, 31 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4f91a68..56c3bdb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fe1651e..857af76 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<tree> cx_error_context (void);
extern bool is_this_parameter (tree);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 7569826..6c6a5c8 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 0000000..39c3ee8
--- /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);