aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2012-05-27 16:25:58 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2012-05-27 16:25:58 +0000
commit253cbc5f37c1c0025b02f977d6fbebc304bdc87e (patch)
treee3ab539b1c4e074d9ad83e5c9cb0254a4ff9fe41 /gcc
parent1ca8bef0218b120d504b18a983b6da1f37f3acbe (diff)
downloadgcc-253cbc5f37c1c0025b02f977d6fbebc304bdc87e.zip
gcc-253cbc5f37c1c0025b02f977d6fbebc304bdc87e.tar.gz
gcc-253cbc5f37c1c0025b02f977d6fbebc304bdc87e.tar.bz2
tree.c (build_constructor): Propagate TREE_SIDE_EFFECTS.
* tree.c (build_constructor): Propagate TREE_SIDE_EFFECTS. testsuite/ * gcc.dg/stmt-expr-4.c: New. From-SVN: r187923
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/stmt-expr-4.c22
-rw-r--r--gcc/tree.c15
4 files changed, 41 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d9c3d16..02b48a0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2012-05-27 Nathan Sidwell <nathan@acm.org>
+
+ * tree.c (build_constructor): Propagate TREE_SIDE_EFFECTS.
+
2012-05-26 Jason Merrill <jason@redhat.com>
PR c++/53220
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 95136c9..4d6b6ff 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2012-05-27 Nathan Sidwell <nathan@acm.org>
+
+ * gcc.dg/stmt-expr-4.c: New.
+
2012-05-26 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/53491
diff --git a/gcc/testsuite/gcc.dg/stmt-expr-4.c b/gcc/testsuite/gcc.dg/stmt-expr-4.c
new file mode 100644
index 0000000..d6d0163
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/stmt-expr-4.c
@@ -0,0 +1,22 @@
+
+/* { dg-options "-O2 -std=gnu99" } */
+/* Internal compiler error in iterative_hash_expr */
+
+struct tree_string
+{
+ char str[1];
+};
+
+union tree_node
+{
+ struct tree_string string;
+};
+
+char *Foo (union tree_node * num_string)
+{
+ char *str = ((union {const char * _q; char * _nq;})
+ ((const char *)(({ __typeof (num_string) const __t
+ = num_string; __t; })
+ ->string.str)))._nq;
+ return str;
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index de4a1c0..e5c19bc 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1416,17 +1416,24 @@ build_constructor (tree type, VEC(constructor_elt,gc) *vals)
unsigned int i;
constructor_elt *elt;
bool constant_p = true;
+ bool side_effects_p = false;
TREE_TYPE (c) = type;
CONSTRUCTOR_ELTS (c) = vals;
FOR_EACH_VEC_ELT (constructor_elt, vals, i, elt)
- if (!TREE_CONSTANT (elt->value))
- {
+ {
+ /* Mostly ctors will have elts that don't have side-effects, so
+ the usual case is to scan all the elements. Hence a single
+ loop for both const and side effects, rather than one loop
+ each (with early outs). */
+ if (!TREE_CONSTANT (elt->value))
constant_p = false;
- break;
- }
+ if (TREE_SIDE_EFFECTS (elt->value))
+ side_effects_p = true;
+ }
+ TREE_SIDE_EFFECTS (c) = side_effects_p;
TREE_CONSTANT (c) = constant_p;
return c;