fix c/2161

Richard Henderson rth@redhat.com
Thu Apr 25 22:40:00 GMT 2002


Aint no way I'm touching the grammar to change it to be
left-recursive (which would cause bison to use bounded
stack space for an arbitrary input file).

In lieu of that, defining yyoverflow so that we have no
arbirary cap on the size of the parse stack seems a 
reasonable fix.

Applied mainline only.


r~


        * c-parse.in (yyoverflow): New.
        * cp/parse.y (yyoverflow): New.
        * g++.dg/parse/stack1.C: New.
        * gcc.dg/20020425-1.c: New.

Index: gcc/c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.135
diff -c -p -d -r1.135 c-parse.in
*** gcc/c-parse.in	25 Apr 2002 06:24:21 -0000	1.135
--- gcc/c-parse.in	26 Apr 2002 05:31:22 -0000
*************** end ifobjc
*** 61,66 ****
--- 61,101 ----
  
  /* Like YYERROR but do call yyerror.  */
  #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
+ 
+ /* Like the default stack expander, except (1) use realloc when possible,
+    and (2) impose no hard maxiumum on stack size.  */
+ #define yyoverflow(MSG, SS, SSSIZE, VS, VSSIZE, YYSSZ)			\
+ do {									\
+   size_t newsize;							\
+   short *newss;								\
+   YYSTYPE *newvs;							\
+   newsize = *(YYSSZ) *= 2;						\
+   if (yyfree_stacks)							\
+     {									\
+       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));	\
+       if (newss)							\
+         memcpy (newss, *(SS), (SSSIZE));				\
+       newvs = (YYSTYPE *) really_call_malloc (newsize * sizeof (YYSTYPE)); \
+       if (newvs)							\
+         memcpy (newvs, *(VS), (VSSIZE));				\
+     }									\
+   if (!newss || !newvs)							\
+     {									\
+       yyerror (MSG);							\
+       return 2;								\
+     }									\
+   yyfree_stacks = 1;							\
+   *(SS) = newss;							\
+   *(VS) = newvs;							\
+ } while (0)
+ 
  %}
  
  %start program
Index: gcc/cp/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parse.y,v
retrieving revision 1.254
diff -c -p -d -r1.254 parse.y
*** gcc/cp/parse.y	25 Apr 2002 06:24:37 -0000	1.254
--- gcc/cp/parse.y	26 Apr 2002 05:31:22 -0000
*************** extern struct obstack permanent_obstack;
*** 48,53 ****
--- 48,87 ----
  /* Like YYERROR but do call yyerror.  */
  #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
  
+ /* Like the default stack expander, except (1) use realloc when possible,
+    and (2) impose no hard maxiumum on stack size.  */
+ #define yyoverflow(MSG, SS, SSSIZE, VS, VSSIZE, YYSSZ)			\
+ do {									\
+   size_t newsize;							\
+   short *newss;								\
+   YYSTYPE *newvs;							\
+   newsize = *(YYSSZ) *= 2;						\
+   if (yyfree_stacks)							\
+     {									\
+       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));	\
+       if (newss)							\
+         memcpy (newss, *(SS), (SSSIZE));				\
+       newvs = (YYSTYPE *) really_call_malloc (newsize * sizeof (YYSTYPE)); \
+       if (newvs)							\
+         memcpy (newvs, *(VS), (VSSIZE));				\
+     }									\
+   if (!newss || !newvs)							\
+     {									\
+       yyerror (MSG);							\
+       return 2;								\
+     }									\
+   yyfree_stacks = 1;							\
+   *(SS) = newss;							\
+   *(VS) = newvs;							\
+ } while (0)
+ 
  #define OP0(NODE) (TREE_OPERAND (NODE, 0))
  #define OP1(NODE) (TREE_OPERAND (NODE, 1))
  
Index: gcc/testsuite/g++.dg/parse/stack1.C
===================================================================
RCS file: gcc/testsuite/g++.dg/parse/stack1.C
diff -N gcc/testsuite/g++.dg/parse/stack1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/parse/stack1.C	26 Apr 2002 05:31:22 -0000
***************
*** 0 ****
--- 1,14 ----
+ /* PR c/2161: parser stack overflow.  */
+ /* { dg-do compile } */
+ 
+ #define ONE	else if (0) { }
+ #define TEN	ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE
+ #define HUN	TEN TEN TEN TEN TEN TEN TEN TEN TEN TEN
+ #define THOU	HUN HUN HUN HUN HUN HUN HUN HUN HUN HUN
+ 
+ void foo()
+ {
+   if (0) { }
+   /* 11,000 else if's.  */
+   THOU THOU THOU THOU THOU THOU THOU THOU THOU THOU THOU
+ }
Index: gcc/testsuite/gcc.dg/20020425-1.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/20020425-1.c
diff -N gcc/testsuite/gcc.dg/20020425-1.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/gcc.dg/20020425-1.c	26 Apr 2002 05:31:23 -0000
***************
*** 0 ****
--- 1,14 ----
+ /* PR c/2161: parser stack overflow.  */
+ /* { dg-do compile } */
+ 
+ #define ONE	else if (0) { }
+ #define TEN	ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE
+ #define HUN	TEN TEN TEN TEN TEN TEN TEN TEN TEN TEN
+ #define THOU	HUN HUN HUN HUN HUN HUN HUN HUN HUN HUN
+ 
+ void foo()
+ {
+   if (0) { }
+   /* 11,000 else if's.  */
+   THOU THOU THOU THOU THOU THOU THOU THOU THOU THOU THOU
+ }



More information about the Gcc-patches mailing list