fix c/2161

Richard Henderson rth@redhat.com
Fri Apr 26 23:56:00 GMT 2002


On Fri, Apr 26, 2002 at 11:59:12AM -0700, Russ Allbery wrote:
> * Use of alloca in parsers
>   If YYSTACK_USE_ALLOCA is defined to 0, then the parsers will use
>   malloc exclusively.  Since 1.29, but was not NEWS'ed.

Yeah, but I'm not going to use that because (1) 1.28 is still common
in distributions and that doesn't work there and (2) it doesn't use
realloc when possible.

I'm committing the following, tested with bison 1.28 and 1.35.


r~


        * 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.

        * parse.y (malloced_yyss, malloced_yyvs): New.
        (yyoverflow): Re-add.  Set them.
        (free_parser_stacks): New.

Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.132
diff -c -p -d -r1.132 c-common.h
*** c-common.h	26 Apr 2002 07:39:55 -0000	1.132
--- c-common.h	27 Apr 2002 06:48:38 -0000
*************** extern tree gettags				PARAMS ((void));
*** 328,333 ****
--- 328,335 ----
  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 *));
Index: c-lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lex.c,v
retrieving revision 1.172
diff -c -p -d -r1.172 c-lex.c
*** c-lex.c	25 Apr 2002 06:24:21 -0000	1.172
--- c-lex.c	27 Apr 2002 06:48:38 -0000
*************** c_common_parse_file (set_yydebug)
*** 159,164 ****
--- 159,165 ----
    cpp_finish_options (parse_in);
  
    yyparse ();
+   free_parser_stacks ();
  }
  
  struct c_fileinfo *
Index: c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.138
diff -c -p -d -r1.138 c-parse.in
*** c-parse.in	26 Apr 2002 17:04:33 -0000	1.138
--- c-parse.in	27 Apr 2002 06:48:38 -0000
*************** end ifobjc
*** 61,66 ****
--- 61,109 ----
  
  /* 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
*************** make_pointer_declarator (type_quals_attr
*** 3907,3910 ****
--- 3950,3965 ----
    if (attrs != NULL_TREE)
      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);
+     }
  }
Index: cp/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parse.y,v
retrieving revision 1.257
diff -c -p -d -r1.257 parse.y
*** cp/parse.y	26 Apr 2002 17:04:37 -0000	1.257
--- cp/parse.y	27 Apr 2002 06:48:39 -0000
*************** extern struct obstack permanent_obstack;
*** 48,53 ****
--- 48,96 ----
  /* 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))
  
*************** debug_yytranslate (value)
*** 3970,3974 ****
  {
    return yytname[YYTRANSLATE (value)];
  }
- 
  #endif
--- 4013,4028 ----
  {
    return yytname[YYTRANSLATE (value)];
  }
  #endif
+ 
+ /* Free malloced parser stacks if necessary.  */
+ 
+ void
+ free_parser_stacks ()
+ {
+   if (malloced_yyss)
+     {
+       free (malloced_yyss);
+       free (malloced_yyvs);
+     }
+ }



More information about the Gcc-patches mailing list