aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-06-11 14:03:41 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-06-11 14:03:41 +0000
commitda10c178007d4edea4ad97f49041c6a6a8c5b02d (patch)
tree0cffaced7fe6d9df00526a6f1fd3cdbebf90a2ab
parent5a5da48013f29c55bd9a4221ebc72104b80e4982 (diff)
downloadgcc-da10c178007d4edea4ad97f49041c6a6a8c5b02d.zip
gcc-da10c178007d4edea4ad97f49041c6a6a8c5b02d.tar.gz
gcc-da10c178007d4edea4ad97f49041c6a6a8c5b02d.tar.bz2
re PR c++/90801 (A recurring hang)
2019-06-11 Richard Biener <rguenther@suse.de> PR c++/90801 * typeck2.c (split_nonconstant_init_1): Avoid ordered remove from CONSTRUCTOR by marking to remove elements and doing all of them in a O(n) scan. From-SVN: r272156
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/typeck2.c31
2 files changed, 27 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 757f3fc..e067ff7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2019-06-11 Richard Biener <rguenther@suse.de>
+
+ PR c++/90801
+ * typeck2.c (split_nonconstant_init_1): Avoid ordered remove
+ from CONSTRUCTOR by marking to remove elements and doing all
+ of them in a O(n) scan.
+
2019-06-11 Jakub Jelinek <jakub@redhat.com>
PR c++/90810
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index e9f759d..dd7e2cb 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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;
+ unsigned HOST_WIDE_INT idx, tidx;
tree field_index, value;
tree type = TREE_TYPE (dest);
tree inner_type = NULL;
@@ -657,7 +657,8 @@ split_nonconstant_init_1 (tree dest, tree init)
if (!split_nonconstant_init_1 (sub, value))
complete_p = false;
else
- CONSTRUCTOR_ELTS (init)->ordered_remove (idx--);
+ /* Mark element for removal. */
+ CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
num_split_elts++;
}
else if (!initializer_constant_valid_p (value, inner_type))
@@ -665,15 +666,8 @@ split_nonconstant_init_1 (tree dest, tree init)
tree code;
tree sub;
- /* FIXME: Ordered removal is O(1) so the whole function is
- worst-case quadratic. This could be fixed using an aside
- bitmap to record which elements must be removed and remove
- them all at the same time. Or by merging
- split_non_constant_init into process_init_constructor_array,
- that is separating constants from non-constants while building
- the vector. */
- CONSTRUCTOR_ELTS (init)->ordered_remove (idx);
- --idx;
+ /* Mark element for removal. */
+ CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
if (TREE_CODE (field_index) == RANGE_EXPR)
{
@@ -711,6 +705,21 @@ split_nonconstant_init_1 (tree dest, tree init)
num_split_elts++;
}
}
+ if (num_split_elts != 0)
+ {
+ /* Perform the delayed ordered removal of non-constant elements
+ we split out. */
+ for (tidx = 0, idx = 0; 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);
+ ++tidx;
+ }
+ vec_safe_truncate (CONSTRUCTOR_ELTS (init), tidx);
+ }
break;
case VECTOR_TYPE: