re PR c++/90801 (A recurring hang)
authorRichard Biener <rguenther@suse.de>
Thu, 13 Jun 2019 08:41:13 +0000 (08:41 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 13 Jun 2019 08:41:13 +0000 (08:41 +0000)
2019-06-13  Richard Biener  <rguenther@suse.de>

PR c++/90801
* typeck2.c (split_nonconstant_init_1): Properly count
num_split_elts, optimize single constructor elt removal.

From-SVN: r272235

gcc/cp/ChangeLog
gcc/cp/typeck2.c

index 37d2b2a3fe8f51adeb50315a4b391b702141c60a..da5dec37b19b0607b353d5a20b746be50da2e50f 100644 (file)
@@ -1,3 +1,9 @@
+2019-06-13  Richard Biener  <rguenther@suse.de>
+
+       PR c++/90801
+       * typeck2.c (split_nonconstant_init_1): Properly count
+       num_split_elts, optimize single constructor elt removal.
+
 2019-06-12  Marek Polacek  <polacek@redhat.com>
 
        PR c++/66999 - 'this' captured by reference.
index dd7e2cb024c22107d5ac965e45830a19b68273d9..0109d6e52f569c1a3c9b0f839e594c96c1c7a4ea 100644 (file)
@@ -603,7 +603,7 @@ cxx_incomplete_type_error (location_t loc, const_tree value, const_tree type)
 static bool
 split_nonconstant_init_1 (tree dest, tree init)
 {
-  unsigned HOST_WIDE_INT idx, tidx;
+  unsigned HOST_WIDE_INT idx, tidx = HOST_WIDE_INT_M1U;
   tree field_index, value;
   tree type = TREE_TYPE (dest);
   tree inner_type = NULL;
@@ -657,9 +657,13 @@ split_nonconstant_init_1 (tree dest, tree init)
              if (!split_nonconstant_init_1 (sub, value))
                complete_p = false;
              else
-               /* Mark element for removal.  */
-               CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
-             num_split_elts++;
+               {
+                 /* Mark element for removal.  */
+                 CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
+                 if (idx < tidx)
+                   tidx = idx;
+                 num_split_elts++;
+               }
            }
          else if (!initializer_constant_valid_p (value, inner_type))
            {
@@ -668,6 +672,8 @@ split_nonconstant_init_1 (tree dest, tree init)
 
              /* Mark element for removal.  */
              CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
+             if (idx < tidx)
+               tidx = idx;
 
              if (TREE_CODE (field_index) == RANGE_EXPR)
                {
@@ -705,17 +711,18 @@ split_nonconstant_init_1 (tree dest, tree init)
              num_split_elts++;
            }
        }
-      if (num_split_elts != 0)
+      if (num_split_elts == 1)
+       CONSTRUCTOR_ELTS (init)->ordered_remove (tidx);
+      else if (num_split_elts > 1)
        {
          /* Perform the delayed ordered removal of non-constant elements
             we split out.  */
-         for (tidx = 0, idx = 0; idx < CONSTRUCTOR_NELTS (init); ++idx)
+         for (idx = tidx; idx < CONSTRUCTOR_NELTS (init); ++idx)
            if (CONSTRUCTOR_ELT (init, idx)->index == NULL_TREE)
              ;
            else
              {
-               if (tidx != idx)
-                 *CONSTRUCTOR_ELT (init, tidx) = *CONSTRUCTOR_ELT (init, idx);
+               *CONSTRUCTOR_ELT (init, tidx) = *CONSTRUCTOR_ELT (init, idx);
                ++tidx;
              }
          vec_safe_truncate (CONSTRUCTOR_ELTS (init), tidx);