bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] api.push-pull: complain about YYSTACK_USE_ALLOCA=1.


From: Joel E. Denny
Subject: [PATCH] api.push-pull: complain about YYSTACK_USE_ALLOCA=1.
Date: Sun, 13 Sep 2009 16:01:49 -0400 (EDT)
User-agent: Alpine 1.00 (DEB 882 2007-12-20)

I'd like to push this patch to master, branch-2.5, and branch-2.4.2 so 
that push parser users are informed that they can't set 
YYSTACK_USE_ALLOCA=1.  The only way I can see to do this is with #error in 
yacc.c.  However, I don't see any other use of #error in the skeletons.  
Is there any reason not to use it?

>From bb6c1be1dca11f798e5fe9a0348a44dfff963908 Mon Sep 17 00:00:00 2001
From: Joel E. Denny <address@hidden>
Date: Sun, 13 Sep 2009 14:03:30 -0400
Subject: [PATCH] api.push-pull: complain about YYSTACK_USE_ALLOCA=1.

Previously it was just ignored for push parsers.
* NEWS (2.4.2): Document.
* data/yacc.c: Implement complaint with #error.
* doc/bison.texinfo (Push Decl): Cross-reference ...
(Table of Symbols): ... the YYSTACK_USE_ALLOCA entry here, and
document the incompatibility.
* tests/push.at (Error for YYSTACK_USE_ALLOCA=1): New test
group.
* tests/torture.at (Exploding the Stack Size with Alloca): For
push parsing, instead of checking that alloca is ignored, just
skip the test.
---
 ChangeLog         |   15 +++++++++++++++
 NEWS              |    9 +++++++++
 data/yacc.c       |   12 ++++++------
 doc/bison.texinfo |   11 +++++++++++
 src/parse-gram.c  |    4 ++--
 src/parse-gram.h  |    2 +-
 tests/push.at     |   23 +++++++++++++++++++++++
 tests/torture.at  |   15 ++-------------
 8 files changed, 69 insertions(+), 22 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f99cc59..d44b065 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
 2009-09-13  Joel E. Denny  <address@hidden>
 
+       api.push-pull: complain about YYSTACK_USE_ALLOCA=1.
+       Previously it was just ignored for push parsers.
+       * NEWS (2.4.2): Document.
+       * data/yacc.c: Implement complaint with #error.
+       * doc/bison.texinfo (Push Decl): Cross-reference ...
+       (Table of Symbols): ... the YYSTACK_USE_ALLOCA entry here, and
+       document the incompatibility.
+       * tests/push.at (Error for YYSTACK_USE_ALLOCA=1): New test
+       group.
+       * tests/torture.at (Exploding the Stack Size with Alloca): For
+       push parsing, instead of checking that alloca is ignored, just
+       skip the test.
+
+2009-09-13  Joel E. Denny  <address@hidden>
+
        tests: clean up push.at test group titles.
        * tests/push.at: Remove "Push Parsing: " from test group titles
        because these are already under the banner "Push Parsing Tests".
diff --git a/NEWS b/NEWS
index 41ab73d..979596d 100644
--- a/NEWS
+++ b/NEWS
@@ -214,6 +214,15 @@ Bison News
   Bison's Java feature as a whole including its current usage of %code
   is still considered experimental.
 
+** Compilation error for push parsers and YYSTACK_USE_ALLOCA=1.
+
+  Push parsers cannot use alloca to reallocate the parsing stacks as
+  they grow because, in order to preserve the stacks between calls to
+  yypush_parse, the stacks are stored in a yypstate instance rather than
+  locally in yypush_parse.  Previously, YYSTACK_USE_ALLOCA=1 was simply
+  ignored in the generated push parser code.  Now, #error is used
+  instead to complain to the user.
+
 ** Internationalization.
 
   Fix a regression introduced in Bison 2.4: Under some circumstances,
diff --git a/data/yacc.c b/data/yacc.c
index 26c5996..0605af3 100644
--- a/data/yacc.c
+++ b/data/yacc.c
@@ -404,11 +404,12 @@ typedef short int yytype_int16;
 
 #if ! defined yyoverflow || YYERROR_VERBOSE
 
-]b4_push_if([],
-[[/* The parser invokes alloca or malloc; define the necessary symbols.  */
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
 
 # ifdef YYSTACK_USE_ALLOCA
-#  if YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA]b4_push_if([[
+    /* Push parser stacks are not locals, so reject alloca requests.  */
+#   error push parsers are not compatible with YYSTACK_USE_ALLOCA=1]], [[
 #   ifdef __GNUC__
 #    define YYSTACK_ALLOC __builtin_alloca
 #   elif defined __BUILTIN_VA_ARG_INCR
@@ -426,12 +427,11 @@ typedef short int yytype_int16;
 #      define _STDLIB_H 1
 #     endif
 #    endif
-#   endif
+#   endif]])[
 #  endif
 # endif
 
-]])dnl
-[# ifdef YYSTACK_ALLOC
+# ifdef YYSTACK_ALLOC
    /* Pacify GCC's `empty if-body' warning.  */
 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
 #  ifndef YYSTACK_ALLOC_MAXIMUM
diff --git a/doc/bison.texinfo b/doc/bison.texinfo
index e3da40a..e8565e8 100644
--- a/doc/bison.texinfo
+++ b/doc/bison.texinfo
@@ -4675,6 +4675,9 @@ Adding the @samp{%define api.pure} declaration does 
exactly the same thing to
 the generated parser with @samp{%define api.push-pull both} as it did for
 @samp{%define api.push-pull push}.
 
+Push parsers are not compatible with @samp{YYSTACK_USE_ALLOCA=1}.
+See @ref{Table of Symbols, , YYSTACK_USE_ALLOCA}.
+
 @node Decl Summary
 @subsection Bison Declaration Summary
 @cindex Bison declaration summary
@@ -10613,6 +10616,14 @@ unchecked stack overflow on any of your target hosts 
when
 @code{alloca} is called.  You can inspect the code that Bison
 generates in order to determine the proper numeric values.  This will
 require some expertise in low-level implementation details.
+
+Push parsers cannot use @code{alloca} to reallocate the parsing stacks
+because, in order to preserve the stacks between calls to
address@hidden, the stacks are stored in a @code{yypstate} instance
+rather than locally in @code{yypush_parse}.
+Thus, if you set @samp{YYSTACK_USE_ALLOCA=1}, @code{#error} is used to
+generate a complaint.
+
 @end deffn
 
 @deffn {Type} YYSTYPE
diff --git a/tests/push.at b/tests/push.at
index 741b362..cde07ab 100644
--- a/tests/push.at
+++ b/tests/push.at
@@ -166,3 +166,26 @@ AT_BISON_CHECK([[input.y]], [[1]], [],
 ]])
 
 AT_CLEANUP
+
+## -------------------------------- ##
+## Error for YYSTACK_USE_ALLOCA=1.  ##
+## -------------------------------- ##
+
+AT_SETUP([[Error for YYSTACK_USE_ALLOCA=1]])
+
+AT_DATA_GRAMMAR([[input.y]],
+[[%define api.push-pull push
+%code {
+  void yyerror (char const *msg);
+  int yylex (void);
+}
+%%
+start: ;
+]])
+AT_BISON_CHECK([[-o input.c input.y]])
+AT_CHECK([[$CC $CFLAGS $CPPFLAGS -c input.c]])
+AT_CHECK([[$CC -DYYSTACK_USE_ALLOCA=0 $CFLAGS $CPPFLAGS -c input.c]])
+AT_CHECK([[$CC -DYYSTACK_USE_ALLOCA=1 $CFLAGS $CPPFLAGS -c input.c \
+           || exit 1]], [[1]], [ignore], [ignore])
+
+AT_CLEANUP
diff --git a/tests/torture.at b/tests/torture.at
index 47435cb..41d9b71 100644
--- a/tests/torture.at
+++ b/tests/torture.at
@@ -479,6 +479,8 @@ m4_pushdef([AT_USE_ALLOCA], [[
 #endif
 ]])
 
+AT_CHECK([[if test x"$BISON_USE_PUSH_FOR_PULL" = x1; then exit 77; fi]])
+
 AT_DATA_STACK_TORTURE([AT_USE_ALLOCA])
 
 # Below the limit of 200.
@@ -492,19 +494,6 @@ AT_PARSER_CHECK([./input 900], 0, [], [ignore],
 AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
                 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
 
-# The push parser can't use alloca since the stacks can't be locals.  This test
-# just helps guarantee we don't let the YYSTACK_USE_ALLOCA feature affect
-# push parsers.
-AT_DATA_STACK_TORTURE([AT_USE_ALLOCA],
-[[%define api.push-pull both
-]])
-AT_PARSER_CHECK([./input 20], 0, [], [ignore],
-                [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
-AT_PARSER_CHECK([./input 900], 0, [], [ignore],
-                [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
-AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
-                [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
-
 m4_popdef([AT_USE_ALLOCA])
 
 AT_CLEANUP
-- 
1.5.4.3





reply via email to

[Prev in Thread] Current Thread [Next in Thread]