aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-02-16 11:42:06 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-02-16 11:42:06 -0500
commit1e163090d5d15d9c26fd89cfee5443418e2e968f (patch)
treef6e1e0d3c41a04ecfbd7c9d4942a3a6ad34a523a /gcc
parent61cee2603036c29761a49c07a6531561ca507ddc (diff)
downloadgcc-1e163090d5d15d9c26fd89cfee5443418e2e968f.zip
gcc-1e163090d5d15d9c26fd89cfee5443418e2e968f.tar.gz
gcc-1e163090d5d15d9c26fd89cfee5443418e2e968f.tar.bz2
PR c++/78572 - ICE with self-modifying array initializer
* constexpr.c (cxx_eval_store_expression): The object we're initializing is outside the constant-expression. From-SVN: r245511
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/constexpr.c9
-rw-r--r--gcc/testsuite/g++.dg/init/array47.C3
3 files changed, 16 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2e94fee..66c491e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2017-02-16 Jason Merrill <jason@redhat.com>
+ PR c++/78572 - ICE with self-modifying array initializer
+ * constexpr.c (cxx_eval_store_expression): The object we're
+ initializing is outside the constant-expression.
+ (cxx_eval_call_expression): Set ctx->call.
+
PR c++/79050 - ICE with undeduced auto and LTO
* decl.c (poplevel): Remove undeduced auto decls.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 004bb45..fc7d46c 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1635,6 +1635,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
constexpr_ctx ctx_with_save_exprs = *ctx;
hash_set<tree> save_exprs;
ctx_with_save_exprs.save_exprs = &save_exprs;
+ ctx_with_save_exprs.call = &new_call;
tree jump_target = NULL_TREE;
cxx_eval_constant_expression (&ctx_with_save_exprs, body,
@@ -3386,7 +3387,13 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
/* And then find/build up our initializer for the path to the subobject
we're initializing. */
tree *valp;
- if (DECL_P (object))
+ if (object == ctx->object && VAR_P (object)
+ && DECL_NAME (object) && ctx->call == NULL)
+ /* The variable we're building up an aggregate initializer for is outside
+ the constant-expression, so don't evaluate the store. We check
+ DECL_NAME to handle TARGET_EXPR temporaries, which are fair game. */
+ valp = NULL;
+ else if (DECL_P (object))
valp = ctx->values->get (object);
else
valp = NULL;
diff --git a/gcc/testsuite/g++.dg/init/array47.C b/gcc/testsuite/g++.dg/init/array47.C
new file mode 100644
index 0000000..e3cb1b8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/array47.C
@@ -0,0 +1,3 @@
+// PR c++/78572
+
+static int array[10] = { array[3]=5, array[7]=3, };