diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index bd8e524..e0f7230 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -23311,6 +23311,9 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p, /* Assume all of the expressions are constant. */ *non_constant_p = false; + unsigned nelts = 0; + int suppress = suppress_location_wrappers; + /* Parse the rest of the list. */ while (true) { @@ -23450,6 +23453,19 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p, if (token->type == CPP_CLOSE_BRACE) break; + /* Suppress location wrappers in a long initializer to save memory + (14179). The cutoff is chosen arbitrarily. */ + const unsigned loc_max = 256; + unsigned incr = 1; + if (TREE_CODE (initializer) == CONSTRUCTOR) + /* Look one level down because it's easy. Looking deeper would require + passing down a nelts pointer, and I don't think multi-level massive + initializers are common enough to justify this. */ + incr = CONSTRUCTOR_NELTS (initializer); + nelts += incr; + if (nelts >= loc_max && (nelts - incr) < loc_max) + ++suppress_location_wrappers; + /* Consume the `,' token. */ cp_lexer_consume_token (parser->lexer); } @@ -23479,6 +23495,8 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p, IDENTIFIER_MARKED (designator) = 0; } + suppress_location_wrappers = suppress; + *designated = first_designator != NULL_TREE; return v; } |