From ffd26145521d15fd0b01f0d53b8477d1da70bbfd Mon Sep 17 00:00:00 2001 From: crowl Date: Fri, 8 Apr 2011 18:42:55 +0000 Subject: [PATCH] In my last PPH change, I eliminated the redundancy in the preprocessor identifier lookaside table by removing the name of the identifier from the head of the macro value. This later led to a buffer overrun in libcpp/symtab.c cpp_lt_replay. The buffer was allocated based on the value string size, which is was no longer large enough to hold the definition string. Split cpp_idents_used.max_length and cpp_lookaside.max_length into max_ident_len and max_value_len. In cpp_lt_replay, allocate the buffer based on the sum of max_ident_len and max_value_len. The simple macro validation scheme for PTH is not sufficient for PPH. In particular, in libcpp, even identifiers that are skipped in preprocessing are entered into the symbol table. We need to ignore these. So, add two macro attributes, used_by_directive and expanded_to_text. If neither of these attributes is set, then the macro is not used and can be ignored for validation and replay. These changes bring the macro validation to a workable state. There may be some fine tuning later. Make an inability to open a PPH file for reading a plain error rather than a fatal error. Fatal errors do not seem to play well with tests. Adjust tests to reflect changes. There is still one unexpected failure, p1mean.cc does not compare equal in assembly. Not yet investigated. Index: gcc/testsuite/ChangeLog.pph 2011-04-06 Lawrence Crowl * g++.dg/pph/p1mean.cc: Now pass validation. * g++.dg/pph/p1stdlib.cc: Likewise. * g++.dg/pph/d1symnotinc.cc: Failure to read is now not fatal. * g++.dg/pph/d1chained.cc: Miscategorized as a failure, ... * g++.dg/pph/c1chained.cc: so it has been renamed. Index: gcc/cp/ChangeLog.pph 2011-04-06 Lawrence Crowl * pph.c (pth_dump_identifiers): Split cpp_idents_used::max_length into max_ident_length and max_value_length. Print used_by_directive and expanded_to_text attributes of macros. (pth_save_identifiers): Split cpp_idents_used::max_length into max_ident_length and max_value_length. Filter out macro that are neither used_by_directive nor expanded_to_text, which requires precounting the number of entries remaining. Save used_by_directive and expanded_to_text attributes of the macros. (pth_load_identifiers): Split cpp_idents_used::max_length into max_ident_length and max_value_length. Restore used_by_directive and expanded_to_text attributes of the macros. (pph_read_file): Make failure to read a pph file a non-fatal error. Index: libcpp/ChangeLog.pph 2011-04-06 Lawrence Crowl * include/cpplib.h (struct cpp_hashnode): Add used_by_directive and expanded_to_text attributes for macros. Take their bits from directive_index, which does not need them. * include/symtab.h (struct cpp_idents_used): Split max_length into max_ident_len and max_value_len. Reorder fields to avoid gaps. (struct cpp_ident_use): Add used_by_directive and expanded_to_text attributes for macros. * internal.h (struct cpp_lookaside): Split max_length into max_ident_len and max_value_len. * macro.c (enter_macro_context): Mark expanded_to_text macro attribute. * directives.c (DIRECTIVE_TABLE): Add sizing comment. (do_define): Mark used_by_directive macro attribute. (do_undef): Likewise. (do_ifdef): Likewise. * expr.c (parse_defined): Mark used_by_directive macro attribute. * symtab.c (cpp_lt_create): Split cpp_lookaside::max_length into max_ident_len and max_value_len. * (lt_macro_value): Likewise. * (lt_lookup): Likewise. * (cpp_lt_capture): Likewise. Also save used_by_directive and expanded_to_text attributes of macros. * (cpp_lt_replay): Split cpp_idents_used::max_lenth into max_ident_len and max_value_len. Allocate a buffer with the sum. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/pph@172204 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog.pph | 15 +++++++ gcc/cp/pph.c | 70 +++++++++++++++++++++++---------- gcc/testsuite/ChangeLog.pph | 8 ++++ gcc/testsuite/g++.dg/pph/c1chained.cc | 3 ++ gcc/testsuite/g++.dg/pph/d1chained.cc | 3 -- gcc/testsuite/g++.dg/pph/d1symnotinc.cc | 3 +- gcc/testsuite/g++.dg/pph/p1mean.cc | 10 ++--- gcc/testsuite/g++.dg/pph/p1stdlib.cc | 4 +- libcpp/ChangeLog.pph | 27 +++++++++++++ libcpp/directives.c | 11 +++++- libcpp/expr.c | 2 + libcpp/include/cpplib.h | 4 +- libcpp/include/symtab.h | 12 ++++-- libcpp/internal.h | 3 +- libcpp/macro.c | 3 ++ libcpp/symtab.c | 30 ++++++++------ 16 files changed, 154 insertions(+), 54 deletions(-) create mode 100644 gcc/testsuite/g++.dg/pph/c1chained.cc delete mode 100644 gcc/testsuite/g++.dg/pph/d1chained.cc diff --git a/gcc/cp/ChangeLog.pph b/gcc/cp/ChangeLog.pph index ee4adae2f52..6731dd05a8c 100644 --- a/gcc/cp/ChangeLog.pph +++ b/gcc/cp/ChangeLog.pph @@ -1,3 +1,18 @@ +2011-04-06 Lawrence Crowl + + * pph.c (pth_dump_identifiers): Split cpp_idents_used::max_length + into max_ident_length and max_value_length. Print used_by_directive + and expanded_to_text attributes of macros. + (pth_save_identifiers): Split cpp_idents_used::max_length into + max_ident_length and max_value_length. Filter out macro that are + neither used_by_directive nor expanded_to_text, which requires + precounting the number of entries remaining. Save used_by_directive + and expanded_to_text attributes of the macros. + (pth_load_identifiers): Split cpp_idents_used::max_length into + max_ident_length and max_value_length. Restore used_by_directive and + expanded_to_text attributes of the macros. + (pph_read_file): Make failure to read a pph file a non-fatal error. + 2011-04-05 Lawrence Crowl * parser.c (cp_lexer_dump_tokens): Remove #ifdef ENABLE_CHECKING. diff --git a/gcc/cp/pph.c b/gcc/cp/pph.c index 82d1e1d6a92..14a62c8aca9 100644 --- a/gcc/cp/pph.c +++ b/gcc/cp/pph.c @@ -475,9 +475,11 @@ static void pth_dump_identifiers (FILE *stream, cpp_idents_used *identifiers) { unsigned int idx, col = 1; + char use, exp; - fprintf (stream, "%u identifiers up to %u chars\n", - identifiers->num_entries, identifiers->max_length); + fprintf (stream, "%u identifiers up to %u chars, vals to %u chars\n", + identifiers->num_entries, identifiers->max_ident_len, + identifiers->max_value_len); for (idx = 0; idx < identifiers->num_entries; ++idx) { cpp_ident_use *ident = identifiers->entries + idx; @@ -487,17 +489,19 @@ pth_dump_identifiers (FILE *stream, cpp_idents_used *identifiers) fprintf (stream, "\n"); col = 1; } + use = ident->used_by_directive ? 'U' : '-'; + exp = ident->expanded_to_text ? 'E' : '-'; if (ident->before_str || ident->after_str) { if (col > 1) fprintf (stream, "\n"); - fprintf (stream, " %s = %s -> %s\n", ident->ident_str, + fprintf (stream, " %s %c%c = %s -> %s\n", ident->ident_str, use, exp, ident->before_str, ident->after_str); col = 1; } else { - fprintf (stream, " %s", ident->ident_str); + fprintf (stream, " %s %c%c", ident->ident_str, use, exp); col += ident->ident_len; } } @@ -764,25 +768,45 @@ pth_debug_state (void) static void pth_save_identifiers (cpp_idents_used *identifiers, pph_stream *stream) { - unsigned int num_entries, id; + unsigned int num_entries, active_entries, id; num_entries = identifiers->num_entries; - pph_output_uint (stream, identifiers->max_length); - pph_output_uint (stream, num_entries); + pph_output_uint (stream, identifiers->max_ident_len); + pph_output_uint (stream, identifiers->max_value_len); + active_entries = 0; for ( id = 0; id < num_entries; ++id ) { cpp_ident_use *entry = identifiers->entries + id; + if (!(entry->used_by_directive || entry->expanded_to_text)) + continue; + ++active_entries; + } + + pph_output_uint (stream, active_entries); + + for ( id = 0; id < num_entries; ++id ) + { + cpp_ident_use *entry = identifiers->entries + id; + + if (!(entry->used_by_directive || entry->expanded_to_text)) + continue; + + /* FIX pph: We are wasting space; ident_len, used_by_directive + and expanded_to_text together could fit into a single uint. */ + + pph_output_uint (stream, entry->used_by_directive); + pph_output_uint (stream, entry->expanded_to_text); - gcc_assert (entry->ident_len <= identifiers->max_length); + gcc_assert (entry->ident_len <= identifiers->max_ident_len); pph_output_string_with_length (stream, entry->ident_str, entry->ident_len); - gcc_assert (entry->before_len <= identifiers->max_length); + gcc_assert (entry->before_len <= identifiers->max_value_len); pph_output_string_with_length (stream, entry->before_str, entry->before_len); - gcc_assert (entry->after_len <= identifiers->max_length); + gcc_assert (entry->after_len <= identifiers->max_value_len); pph_output_string_with_length (stream, entry->after_str, entry->after_len); } @@ -1041,11 +1065,13 @@ static void pth_load_identifiers (cpp_idents_used *identifiers, pph_stream *stream) { unsigned int j; - unsigned int max_length, num_entries; + unsigned int max_ident_len, max_value_len, num_entries; unsigned int ident_len, before_len, after_len; - max_length = pph_input_uint (stream); - identifiers->max_length = max_length; + max_ident_len = pph_input_uint (stream); + identifiers->max_ident_len = max_ident_len; + max_value_len = pph_input_uint (stream); + identifiers->max_value_len = max_value_len; num_entries = pph_input_uint (stream); identifiers->num_entries = num_entries; identifiers->entries = XCNEWVEC (cpp_ident_use, num_entries); @@ -1061,7 +1087,10 @@ pth_load_identifiers (cpp_idents_used *identifiers, pph_stream *stream) /* Read the identifiers in HUNK. */ for (j = 0; j < num_entries; ++j) { - const char *s = pph_input_string (stream); + const char *s; + identifiers->entries[j].used_by_directive = pph_input_uint (stream); + identifiers->entries[j].expanded_to_text = pph_input_uint (stream); + s = pph_input_string (stream); gcc_assert (s); ident_len = strlen (s); identifiers->entries[j].ident_len = ident_len; @@ -1946,12 +1975,13 @@ pph_read_file (const char *filename) fprintf (pph_logfile, "PPH: Reading %s\n", filename); stream = pph_stream_open (filename, "rb"); - if (!stream) - fatal_error ("Cannot open PPH file for reading: %s: %m", filename); - - pph_read_file_contents (stream); - - pph_stream_close (stream); + if (stream) + { + pph_read_file_contents (stream); + pph_stream_close (stream); + } + else + error ("Cannot open PPH file for reading: %s: %m", filename); } /* Record a #include or #include_next for PTH. */ diff --git a/gcc/testsuite/ChangeLog.pph b/gcc/testsuite/ChangeLog.pph index 7b36f6f2010..806e96aacb4 100644 --- a/gcc/testsuite/ChangeLog.pph +++ b/gcc/testsuite/ChangeLog.pph @@ -1,3 +1,11 @@ +2011-04-06 Lawrence Crowl + + * g++.dg/pph/p1mean.cc: Now pass validation. + * g++.dg/pph/p1stdlib.cc: Likewise. + * g++.dg/pph/d1symnotinc.cc: Failure to read is now not fatal. + * g++.dg/pph/d1chained.cc: Miscategorized as a failure, ... + * g++.dg/pph/c1chained.cc: so it has been renamed. + 2011-03-09 Diego Novillo * lib/dg-pth.exp: New. diff --git a/gcc/testsuite/g++.dg/pph/c1chained.cc b/gcc/testsuite/g++.dg/pph/c1chained.cc new file mode 100644 index 00000000000..838f2346204 --- /dev/null +++ b/gcc/testsuite/g++.dg/pph/c1chained.cc @@ -0,0 +1,3 @@ +#include "c1chained1.h" +#include "c1chained2.h" +int x = TWO; diff --git a/gcc/testsuite/g++.dg/pph/d1chained.cc b/gcc/testsuite/g++.dg/pph/d1chained.cc deleted file mode 100644 index 15e16002825..00000000000 --- a/gcc/testsuite/g++.dg/pph/d1chained.cc +++ /dev/null @@ -1,3 +0,0 @@ -#include "c1chained1.h" -#include "c1chained2.h" // { dg-error "fails macro validation" } -int x = TWO; diff --git a/gcc/testsuite/g++.dg/pph/d1symnotinc.cc b/gcc/testsuite/g++.dg/pph/d1symnotinc.cc index b9316fd9628..db014e97319 100644 --- a/gcc/testsuite/g++.dg/pph/d1symnotinc.cc +++ b/gcc/testsuite/g++.dg/pph/d1symnotinc.cc @@ -1,5 +1,4 @@ -// { dg-bogus "Cannot open PPH file for reading" "" { xfail *-*-* } } +// { dg-error "Cannot open PPH file for reading" } #define NAME v #define VALUE 1 #include "d1symnotinc.h" -// { dg-excess-errors "compilation terminated" { xfail *-*-* } } diff --git a/gcc/testsuite/g++.dg/pph/p1mean.cc b/gcc/testsuite/g++.dg/pph/p1mean.cc index 71a0b8f5726..82435bacc2f 100644 --- a/gcc/testsuite/g++.dg/pph/p1mean.cc +++ b/gcc/testsuite/g++.dg/pph/p1mean.cc @@ -1,9 +1,7 @@ -#include // {dg-error fails macro validation "" { xfail *-*-* } } -#include // {dg-error fails macro validation "" { xfail *-*-* } } -#include // {dg-error fails macro validation "" { xfail *-*-* } } -#include // {dg-error fails macro validation "" { xfail *-*-* } } -// { dg-excess-errors "In file included from" { xfail *-*-* } } -// { dg-excess-errors "assembly comparison" { xfail *-*-* } } +#include +#include +#include +#include static unsigned long long MAX_ITEMS = 10000; diff --git a/gcc/testsuite/g++.dg/pph/p1stdlib.cc b/gcc/testsuite/g++.dg/pph/p1stdlib.cc index a6ade5041af..21b9aaf87af 100644 --- a/gcc/testsuite/g++.dg/pph/p1stdlib.cc +++ b/gcc/testsuite/g++.dg/pph/p1stdlib.cc @@ -1,6 +1,4 @@ -#include // { dg-error "fails macro validation" "" { xfail *-*-* } } -// { dg-excess-errors "In file included from" { xfail *-*-* } } -// { dg-excess-errors "regular compilation failed" { xfail *-*-* } } +#include int f(const char* s) { diff --git a/libcpp/ChangeLog.pph b/libcpp/ChangeLog.pph index 799ce41b541..6c537a54af8 100644 --- a/libcpp/ChangeLog.pph +++ b/libcpp/ChangeLog.pph @@ -1,3 +1,30 @@ +2011-04-06 Lawrence Crowl + + * include/cpplib.h (struct cpp_hashnode): Add used_by_directive and + expanded_to_text attributes for macros. Take their bits from + directive_index, which does not need them. + * include/symtab.h (struct cpp_idents_used): Split max_length into + max_ident_len and max_value_len. Reorder fields to avoid gaps. + (struct cpp_ident_use): Add used_by_directive and expanded_to_text + attributes for macros. + * internal.h (struct cpp_lookaside): Split max_length into + max_ident_len and max_value_len. + * macro.c (enter_macro_context): Mark expanded_to_text macro attribute. + * directives.c (DIRECTIVE_TABLE): Add sizing comment. + (do_define): Mark used_by_directive macro attribute. + (do_undef): Likewise. + (do_ifdef): Likewise. + * expr.c (parse_defined): Mark used_by_directive macro attribute. + * symtab.c (cpp_lt_create): Split cpp_lookaside::max_length into + max_ident_len and max_value_len. + * (lt_macro_value): Likewise. + * (lt_lookup): Likewise. + * (cpp_lt_capture): Likewise. Also save used_by_directive and + expanded_to_text attributes of macros. + * (cpp_lt_replay): Split cpp_idents_used::max_lenth into + max_ident_len and max_value_len. Allocate a buffer with the sum. + + 2011-03-04 Lawrence Crowl * symtab.h (cpp_lt_verify_1): Temporary new function. diff --git a/libcpp/directives.c b/libcpp/directives.c index c9b2a68d058..7812b57cf94 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -137,7 +137,10 @@ static void cpp_pop_definition (cpp_reader *, struct def_pragma_macro *); pcmcia-cs-3.0.9). This is no longer important as directive lookup is now O(1). All extensions other than #warning, #include_next, and #import are deprecated. The name is where the extension - appears to have come from. */ + appears to have come from. + + Make sure the bitfield directive_index in include/cpplib.h is large + enough to index the entire table. */ #define DIRECTIVE_TABLE \ D(define, T_DEFINE = 0, KANDR, IN_I) /* 270554 */ \ @@ -580,6 +583,8 @@ do_define (cpp_reader *pfile) if (pfile->cb.before_define) pfile->cb.before_define (pfile); + node->used_by_directive = 1; + if (_cpp_create_definition (pfile, node)) if (pfile->cb.define) pfile->cb.define (pfile, pfile->directive_line, node); @@ -602,6 +607,8 @@ do_undef (cpp_reader *pfile) if (pfile->cb.undef) pfile->cb.undef (pfile, pfile->directive_line, node); + node->used_by_directive = 1; + /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified identifier is not currently defined as a macro name. */ if (node->type == NT_MACRO) @@ -1819,6 +1826,7 @@ do_ifdef (cpp_reader *pfile) if (node) { + node->used_by_directive = 1; /* Do not treat conditional macros as being defined. This is due to the powerpc and spu ports using conditional macros for 'vector', 'bool', and 'pixel' to act as conditional keywords. This messes @@ -1865,6 +1873,7 @@ do_ifndef (cpp_reader *pfile) if (node) { + node->used_by_directive = 1; /* Do not treat conditional macros as being defined. This is due to the powerpc and spu ports using conditional macros for 'vector', 'bool', and 'pixel' to act as conditional keywords. This messes diff --git a/libcpp/expr.c b/libcpp/expr.c index 3c36127b54f..a38bcb2bf8e 100644 --- a/libcpp/expr.c +++ b/libcpp/expr.c @@ -665,6 +665,7 @@ parse_defined (cpp_reader *pfile) if (token->type == CPP_NAME) { node = token->val.node.node; + node->used_by_directive = 1; if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN) { cpp_error (pfile, CPP_DL_ERROR, "missing ')' after \"defined\""); @@ -803,6 +804,7 @@ eval_token (cpp_reader *pfile, const cpp_token *token) } else { + token->val.node.node->used_by_directive = 1; result.high = 0; result.low = 0; if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval) diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index ee6806d2878..3dc41392d9f 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -651,9 +651,11 @@ union GTY(()) _cpp_hashnode_value { struct GTY(()) cpp_hashnode { struct ht_identifier ident; unsigned int is_directive : 1; - unsigned int directive_index : 7; /* If is_directive, + unsigned int directive_index : 5; /* If is_directive, then index into directive table. Otherwise, a NODE_OPERATOR. */ + unsigned int used_by_directive : 1; /* In an active #if, #define etc. */ + unsigned int expanded_to_text : 1; /* Produces tokens for parser. */ unsigned char rid_code; /* Rid code - for front ends. */ ENUM_BITFIELD(node_type) type : 6; /* CPP node type. */ unsigned int flags : 10; /* CPP flags. */ diff --git a/libcpp/include/symtab.h b/libcpp/include/symtab.h index d9e998ef0ab..b5d6492e8a5 100644 --- a/libcpp/include/symtab.h +++ b/libcpp/include/symtab.h @@ -110,17 +110,21 @@ typedef struct cpp_lookaside cpp_lookaside; typedef struct GTY(()) cpp_ident_use { - unsigned int ident_len; const char *ident_str; - unsigned int before_len; const char *before_str; - unsigned int after_len; const char *after_str; + unsigned int ident_len; + unsigned int before_len; + unsigned int after_len; + bool used_by_directive; + bool expanded_to_text; + /* FIX pph: We can reduce the space by shortening ident_len. */ } cpp_ident_use; typedef struct GTY(()) cpp_idents_used { - unsigned int max_length; + unsigned int max_ident_len; + unsigned int max_value_len; unsigned int num_entries; cpp_ident_use *entries; struct obstack * GTY((skip)) strings; diff --git a/libcpp/internal.h b/libcpp/internal.h index 1f9601a01e1..31bb477b839 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -341,7 +341,8 @@ struct cpp_lookaside { unsigned int sticky_order; /* For resizing when capturing the entries. */ unsigned int active; /* Number of active entries. */ struct obstack *strings; /* For macro value storage. */ - unsigned int max_length; /* Largest string encountered. */ + unsigned int max_ident_len; /* Largest identifier encountered. */ + unsigned int max_value_len; /* Largest macro value encountered. */ /* Table usage statistics. */ unsigned long long searches; /* Number of calls to lt_lookup. */ diff --git a/libcpp/macro.c b/libcpp/macro.c index 93edaf9229c..f4be3612256 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -880,6 +880,8 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, /* Disable the macro within its expansion. */ node->flags |= NODE_DISABLED; + node->expanded_to_text = 1; + if (!(node->flags & NODE_USED)) { node->flags |= NODE_USED; @@ -1268,6 +1270,7 @@ cpp_get_token (cpp_reader *pfile) break; node = result->val.node.node; + node->expanded_to_text = 1; if (node->type != NT_MACRO || (result->flags & NO_EXPAND)) break; diff --git a/libcpp/symtab.c b/libcpp/symtab.c index d9ab2367638..4101635b644 100644 --- a/libcpp/symtab.c +++ b/libcpp/symtab.c @@ -411,7 +411,8 @@ cpp_lt_create (unsigned int order, unsigned int debug) table->sticky_order = order; table->active = 0; - table->max_length = 0; + table->max_ident_len = 0; + table->max_value_len = 0; table->strings = XCNEW (struct obstack); /* Strings need no alignment. */ _obstack_begin (table->strings, 0, 0, @@ -556,8 +557,8 @@ lt_macro_value (const char** string, cpp_lookaside *aside, const char *definition = lt_query_macro (reader, cpp_node); size_t macro_len = strlen (definition); *string = (const char *) obstack_copy0 (aside->strings, definition, macro_len); - if (macro_len > aside->max_length) - aside->max_length = macro_len; + if (macro_len > aside->max_value_len) + aside->max_value_len = macro_len; ++aside->macrovalue; return macro_len; } @@ -585,17 +586,17 @@ cpp_lt_capture (cpp_reader *reader) hashnode node = table_entry->node; if (node) { - cpp_ident_use *summary_entry; - cpp_hashnode *cpp_node; + cpp_ident_use *summary_entry = used.entries + summary_index++; + cpp_hashnode *cpp_node = CPP_HASHNODE (node); - summary_entry = used.entries + summary_index++; + summary_entry->used_by_directive = cpp_node->used_by_directive; + summary_entry->expanded_to_text = cpp_node->expanded_to_text; summary_entry->ident_len = node->len; summary_entry->ident_str = (const char *)node->str; summary_entry->before_len = table_entry->length; summary_entry->before_str = table_entry->value; /* Capture any macro value. */ - cpp_node = CPP_HASHNODE (node); if (cpp_node->type == NT_MACRO) summary_entry->after_len = lt_macro_value (&summary_entry->after_str, aside, reader, cpp_node); @@ -606,7 +607,8 @@ cpp_lt_capture (cpp_reader *reader) /* Take the strings from the table and give to the summary. */ used.strings = aside->strings; aside->strings = NULL; - used.max_length = aside->max_length; + used.max_ident_len = aside->max_ident_len; + used.max_value_len = aside->max_value_len; aside->iterations += slots; ++aside->empties; @@ -635,7 +637,8 @@ cpp_lt_capture (cpp_reader *reader) aside->active = 0; /* Create a new string table. */ - aside->max_length = 0; + aside->max_ident_len = 0; + aside->max_value_len = 0; aside->strings = XCNEW (struct obstack); /* Strings need no alignment. */ _obstack_begin (aside->strings, 0, 0, @@ -815,7 +818,8 @@ cpp_lt_replay (cpp_reader *reader, cpp_idents_used* identifiers) unsigned int i; unsigned int num_entries = identifiers->num_entries; cpp_ident_use *entries = identifiers->entries; - char *buffer = XCNEWVEC (char, identifiers->max_length + 1); + char *buffer = XCNEWVEC (char, identifiers->max_ident_len + + identifiers->max_value_len + 1); /* Prevent the lexer from invalidating the tokens we've read so far. */ reader->keep_tokens++; @@ -968,13 +972,13 @@ lt_lookup (cpp_reader *reader, ++aside->active; entries[index].node = node; entries[index].hash = hash; - if (length > aside->max_length) - aside->max_length = length; + if (length > aside->max_ident_len) + aside->max_ident_len = length; /* Capture any macro value. */ if (cpp_node->type == NT_MACRO) entries[index].length = lt_macro_value - (&entries[index].value, aside, reader, cpp_node); + (&entries[index].value, aside, reader, cpp_node); /* else .value and .length are still zero from initialization. */ /* Check table load factor. */ -- 2.11.4.GIT