]> git.saurik.com Git - bison.git/blobdiff - tests/glr-regression.at
Avoid memory leaks by not invoking longjmp in yyreportAmbiguity.
[bison.git] / tests / glr-regression.at
index 8e6cd7808adf5e3030c54f441c609f496f749a4e..54c02f5614797f3f5b86558d86424640b17f7d7a 100644 (file)
@@ -864,7 +864,7 @@ main (void)
 }
 ]])
 
-AT_CHECK([[bison -t -o glr-regr10.c glr-regr10.y]], 0, [],
+AT_CHECK([[bison -o glr-regr10.c glr-regr10.y]], 0, [],
 [glr-regr10.y: conflicts: 1 reduce/reduce
 ])
 AT_COMPILE([glr-regr10])
@@ -930,7 +930,7 @@ main (void)
 }
 ]])
 
-AT_CHECK([[bison -t -o glr-regr11.c glr-regr11.y]], 0, [],
+AT_CHECK([[bison -o glr-regr11.c glr-regr11.y]], 0, [],
 [glr-regr11.y: conflicts: 1 reduce/reduce
 ])
 AT_COMPILE([glr-regr11])
@@ -941,34 +941,75 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## Leaked merged semantic value if user action cuts parse.                  ##
+## Leaked semantic values if user action cuts parse.                        ##
 ## ------------------------------------------------------------------------- ##
 
-AT_SETUP([Leaked merged semantic value if user action cuts parse])
+AT_SETUP([Leaked semantic values if user action cuts parse])
 
 AT_DATA_GRAMMAR([glr-regr12.y],
 [[
 %glr-parser
 %union { int dummy; }
-%type <dummy> start
-%destructor { has_value = 0; } start
+%token PARENT_RHS_AFTER
+%type <dummy> parent_rhs_before merged PARENT_RHS_AFTER
+%destructor { parent_rhs_before_value = 0; } parent_rhs_before
+%destructor { merged_value = 0; } merged
+%destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER
 
 %{
 # include <stdlib.h>
   static int merge (YYSTYPE, YYSTYPE);
   static void yyerror (char const *);
   static int yylex (void);
-  static int has_value = 0;
+  static int parent_rhs_before_value = 0;
+  static int merged_value = 0;
+  static int parent_rhs_after_value = 0;
 # define USE(val)
 %}
 
 %%
 
 start:
-    %merge<merge> { has_value = 1; USE ($$); }
-  | %merge<merge> { USE ($$); YYACCEPT; }
+  alt1 %dprec 1
+  | alt2 %dprec 2
+  ; 
+
+alt1:
+  PARENT_RHS_AFTER {
+    USE ($1);
+    parent_rhs_after_value = 0;
+  }
+  ;
+
+alt2:
+  parent_rhs_before merged PARENT_RHS_AFTER {
+    USE (($1, $2, $3));
+    parent_rhs_before_value = 0;
+    merged_value = 0;
+    parent_rhs_after_value = 0;
+  }
+  ;
+
+parent_rhs_before:
+  {
+    USE ($$);
+    parent_rhs_before_value = 1;
+  }
+  ;
+
+merged:
+  %merge<merge> {
+    USE ($$);
+    merged_value = 1;
+  }
+  | cut %merge<merge> {
+    USE ($$);
+    merged_value = 1;
+  }
   ;
 
+cut: { YYACCEPT; } ;
+
 %%
 
 static int
@@ -988,24 +1029,38 @@ yyerror (char const *msg)
 static int
 yylex (void)
 {
-  return 0;
+  static int const input[] = { PARENT_RHS_AFTER, 0 };
+  static const int *inputp = input;
+  if (*inputp == PARENT_RHS_AFTER)
+    parent_rhs_after_value = 1;
+  return *inputp++;
 }
 
 int
 main (void)
 {
   int exit_status = yyparse ();
-  if (has_value)
+  if (parent_rhs_before_value)
     {
-      fprintf (stderr, "Destructor not called.\n");
-      return 1;
+      fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
+      exit_status = 1;
+    }
+  if (merged_value)
+    {
+      fprintf (stderr, "`merged' destructor not called.\n");
+      exit_status = 1;
+    }
+  if (parent_rhs_after_value)
+    {
+      fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
+      exit_status = 1;
     }
   return exit_status;
 }
 ]])
 
-AT_CHECK([[bison -t -o glr-regr12.c glr-regr12.y]], 0, [],
-[glr-regr12.y: conflicts: 1 reduce/reduce
+AT_CHECK([[bison -o glr-regr12.c glr-regr12.y]], 0, [],
+[glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce
 ])
 AT_COMPILE([glr-regr12])
 
@@ -1131,7 +1186,7 @@ main (void)
 }
 ]])
 
-AT_CHECK([[bison -t -o glr-regr13.c glr-regr13.y]], 0, [], [])
+AT_CHECK([[bison -o glr-regr13.c glr-regr13.y]], 0, [], [])
 AT_COMPILE([glr-regr13])
 
 AT_CHECK([[./glr-regr13]], 0,
@@ -1344,7 +1399,7 @@ main (void)
 }
 ]])
 
-AT_CHECK([[bison -t -o glr-regr14.c glr-regr14.y]], 0, [],
+AT_CHECK([[bison -o glr-regr14.c glr-regr14.y]], 0, [],
 [glr-regr14.y: conflicts: 3 reduce/reduce
 ])
 AT_COMPILE([glr-regr14])
@@ -1365,3 +1420,95 @@ start <- merge 'c' stack_explosion:
 ], [])
 
 AT_CLEANUP
+
+
+## ------------------------------------------------------------------------- ##
+## Leaked semantic values when reporting ambiguity.                         ##
+## ------------------------------------------------------------------------- ##
+
+AT_SETUP([Leaked semantic values when reporting ambiguity])
+
+AT_DATA_GRAMMAR([glr-regr15.y],
+[[
+%glr-parser
+%union { int dummy; }
+%type <dummy> parent_rhs_before
+%destructor { parent_rhs_before_value = 0; } parent_rhs_before
+
+%{
+# include <stdlib.h>
+  static void yyerror (char const *);
+  static int yylex (void);
+  static int parent_rhs_before_value = 0;
+# define USE(val)
+%}
+
+%%
+
+start:
+  alt1 %dprec 1
+  | alt2 %dprec 2
+  ;
+
+/* This stack must be merged into the other stacks *last* (added at the
+   beginning of the semantic options list) so that yyparse will choose to clean
+   it up rather than the tree for which some semantic actions have been
+   performed.  Thus, if yyreportAmbiguity longjmp's to yyparse, the values from
+   those other trees are not cleaned up.  */
+alt1: ;
+
+alt2:
+  parent_rhs_before ambiguity {
+    USE ($1);
+    parent_rhs_before_value = 0;
+  }
+  ;
+
+parent_rhs_before:
+  {
+    USE ($$);
+    parent_rhs_before_value = 1;
+  }
+  ;
+
+ambiguity: ambiguity1 | ambiguity2 ;
+ambiguity1: ;
+ambiguity2: ;
+
+%%
+
+static void
+yyerror (char const *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+}
+
+static int
+yylex (void)
+{
+  return 0;
+}
+
+int
+main (void)
+{
+  int exit_status = yyparse () != 1;
+  if (parent_rhs_before_value)
+    {
+      fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
+      exit_status = 1;
+    }
+  return exit_status;
+}
+]])
+
+AT_CHECK([[bison -o glr-regr15.c glr-regr15.y]], 0, [],
+[glr-regr15.y: conflicts: 2 reduce/reduce
+])
+AT_COMPILE([glr-regr15])
+
+AT_CHECK([[./glr-regr15]], 0, [],
+[syntax is ambiguous
+])
+
+AT_CLEANUP