diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4b54744f9e..0fd205f5b13 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2002-04-26 Richard Henderson + + * c-parse.in (malloced_yyss, malloced_yyvs): New. + (yyoverflow): Re-add. Set them. + (free_parser_stacks): New. + * c-common.h: Declare it. + * c-lex.c (c_common_parse_file): Call it. + 2002-04-26 Richard Henderson * cfgrtl.c (tidy_fallthru_edge): Don't use next_real_insn diff --git a/gcc/c-common.h b/gcc/c-common.h index 873fa4a2919..a8439d4966a 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -328,6 +328,8 @@ extern tree gettags PARAMS ((void)); extern int (*lang_missing_noreturn_ok_p) PARAMS ((tree)); extern int yyparse PARAMS ((void)); +extern void free_parser_stacks PARAMS ((void)); + extern stmt_tree current_stmt_tree PARAMS ((void)); extern tree *current_scope_stmt_stack PARAMS ((void)); extern void begin_stmt_tree PARAMS ((tree *)); diff --git a/gcc/c-lex.c b/gcc/c-lex.c index 30ef877f0b9..acdcf340c32 100644 --- a/gcc/c-lex.c +++ b/gcc/c-lex.c @@ -159,6 +159,7 @@ c_common_parse_file (set_yydebug) cpp_finish_options (parse_in); yyparse (); + free_parser_stacks (); } struct c_fileinfo * diff --git a/gcc/c-parse.in b/gcc/c-parse.in index ff279a10079..679d42d0089 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -61,6 +61,49 @@ end ifobjc /* Like YYERROR but do call yyerror. */ #define YYERROR1 { yyerror ("syntax error"); YYERROR; } + +/* Like the default stack expander, except (1) use realloc when possible, + (2) impose no hard maxiumum on stack size, (3) REALLY do not use alloca. + + Irritatingly, YYSTYPE is defined after this %{ %} block, so we cannot + give malloced_yyvs its proper type. This is ok since all we need from + it is to be able to free it. */ + +static short *malloced_yyss; +static void *malloced_yyvs; + +#define yyoverflow(MSG, SS, SSSIZE, VS, VSSIZE, YYSSZ) \ +do { \ + size_t newsize; \ + short *newss; \ + YYSTYPE *newvs; \ + newsize = *(YYSSZ) *= 2; \ + if (malloced_yyss) \ + { \ + newss = (short *) \ + really_call_realloc (*(SS), newsize * sizeof (short)); \ + newvs = (YYSTYPE *) \ + really_call_realloc (*(VS), newsize * sizeof (YYSTYPE)); \ + } \ + else \ + { \ + newss = (short *) really_call_malloc (newsize * sizeof (short)); \ + newvs = (YYSTYPE *) really_call_malloc (newsize * sizeof (YYSTYPE)); \ + if (newss) \ + memcpy (newss, *(SS), (SSSIZE)); \ + if (newvs) \ + memcpy (newvs, *(VS), (VSSIZE)); \ + } \ + if (!newss || !newvs) \ + { \ + yyerror (MSG); \ + return 2; \ + } \ + *(SS) = newss; \ + *(VS) = newvs; \ + malloced_yyss = newss; \ + malloced_yyvs = (void *) newvs; \ +} while (0) %} %start program @@ -3908,3 +3951,15 @@ make_pointer_declarator (type_quals_attrs, target) itarget = tree_cons (attrs, target, NULL_TREE); return build1 (INDIRECT_REF, quals, itarget); } + +/* Free malloced parser stacks if necessary. */ + +void +free_parser_stacks () +{ + if (malloced_yyss) + { + free (malloced_yyss); + free (malloced_yyvs); + } +} diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4e9ef3ce8ad..237d66964cd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2002-04-26 Richard Henderson + + * parse.y (malloced_yyss, malloced_yyvs): New. + (yyoverflow): Re-add. Set them. + (free_parser_stacks): New. + 2002-04-26 Mark Mitchell PR c++/6497 diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 0f963619495..2574d1dd061 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -48,6 +48,49 @@ extern struct obstack permanent_obstack; /* Like YYERROR but do call yyerror. */ #define YYERROR1 { yyerror ("syntax error"); YYERROR; } +/* Like the default stack expander, except (1) use realloc when possible, + (2) impose no hard maxiumum on stack size, (3) REALLY do not use alloca. + + Irritatingly, YYSTYPE is defined after this %{ %} block, so we cannot + give malloced_yyvs its proper type. This is ok since all we need from + it is to be able to free it. */ + +static short *malloced_yyss; +static void *malloced_yyvs; + +#define yyoverflow(MSG, SS, SSSIZE, VS, VSSIZE, YYSSZ) \ +do { \ + size_t newsize; \ + short *newss; \ + YYSTYPE *newvs; \ + newsize = *(YYSSZ) *= 2; \ + if (malloced_yyss) \ + { \ + newss = (short *) \ + really_call_realloc (*(SS), newsize * sizeof (short)); \ + newvs = (YYSTYPE *) \ + really_call_realloc (*(VS), newsize * sizeof (YYSTYPE)); \ + } \ + else \ + { \ + newss = (short *) really_call_malloc (newsize * sizeof (short)); \ + newvs = (YYSTYPE *) really_call_malloc (newsize * sizeof (YYSTYPE)); \ + if (newss) \ + memcpy (newss, *(SS), (SSSIZE)); \ + if (newvs) \ + memcpy (newvs, *(VS), (VSSIZE)); \ + } \ + if (!newss || !newvs) \ + { \ + yyerror (MSG); \ + return 2; \ + } \ + *(SS) = newss; \ + *(VS) = newvs; \ + malloced_yyss = newss; \ + malloced_yyvs = (void *) newvs; \ +} while (0) + #define OP0(NODE) (TREE_OPERAND (NODE, 0)) #define OP1(NODE) (TREE_OPERAND (NODE, 1)) @@ -3970,5 +4013,16 @@ debug_yytranslate (value) { return yytname[YYTRANSLATE (value)]; } - #endif + +/* Free malloced parser stacks if necessary. */ + +void +free_parser_stacks () +{ + if (malloced_yyss) + { + free (malloced_yyss); + free (malloced_yyvs); + } +}