tree.c (build_constructor): Propagate TREE_SIDE_EFFECTS.
authorNathan Sidwell <nathan@acm.org>
Sun, 27 May 2012 16:25:58 +0000 (16:25 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Sun, 27 May 2012 16:25:58 +0000 (16:25 +0000)
* tree.c (build_constructor): Propagate TREE_SIDE_EFFECTS.
testsuite/
* gcc.dg/stmt-expr-4.c: New.

From-SVN: r187923

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/stmt-expr-4.c [new file with mode: 0644]
gcc/tree.c

index d9c3d166169bc964743fa632d050b0bfc2cc67de..02b48a025dc7efbd492552fed7647009fb6fbf14 100644 (file)
@@ -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
index 95136c99c0325441ae587f7c943baaa87ea61b7d..4d6b6ffe1412e944fa7a9fa6169203f12ea37b7e 100644 (file)
@@ -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 (file)
index 0000000..d6d0163
--- /dev/null
@@ -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;
+}
index de4a1c042022a2b4d5ba666defe52c1cdade9604..e5c19bccabfcfc4e06bbaa4ca9e12ed2f26a994f 100644 (file)
@@ -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;