diff options
author | Richard Biener <rguenther@suse.de> | 2019-06-11 14:03:41 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2019-06-11 14:03:41 +0000 |
commit | da10c178007d4edea4ad97f49041c6a6a8c5b02d (patch) | |
tree | 0cffaced7fe6d9df00526a6f1fd3cdbebf90a2ab | |
parent | 5a5da48013f29c55bd9a4221ebc72104b80e4982 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 31 |
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: |