bison-patches
[Top][All Lists]
Advanced

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

lalr1.cc: fix stack symbol move


From: Akim Demaille
Subject: lalr1.cc: fix stack symbol move
Date: Thu, 18 Oct 2018 13:22:47 +0200

Bison 3.1.90 has a flaw in it handling of its stack.
Found while testing on Vcsn.

commit 3967e46a2dd3f6fea34a468b1d6207747b3f1832
Author: Akim Demaille <address@hidden>
Date:   Thu Oct 18 07:07:32 2018 +0200

    lalr1.cc: fix stack symbol move
    
    In some casing, once we moved a stack symbol, we forget to mark the
    source stack symbol as emptied.  As a consequence, it may be destroyed
    a second time.
    
    This happens when the stack has to be resized.
    
    * data/lalr1.cc (stack_symbol_type::stack_symbol_type): Record that
    the source was emptied.
    (stack_symbol_type::operator=): Likewise.
    * tests/c++.at (C++ Variant-based Symbols Unit Tests): Force the stack
    to be resized.  Check its content.

diff --git a/data/lalr1.cc b/data/lalr1.cc
index cb8d6069..f80476db 100644
--- a/data/lalr1.cc
+++ b/data/lalr1.cc
@@ -602,6 +602,10 @@ m4_if(b4_prefix, [yy], [],
   {]b4_variant_if([
     b4_symbol_variant([that.type_get ()],
                       [value], [YY_MOVE_OR_COPY], [YY_MOVE (that.value)])])[
+#if defined __cplusplus && 201103L <= __cplusplus
+    // that is emptied.
+    that.state = empty_state;
+#endif
   }
 
   ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type (state_type s, 
YY_MOVE_REF (symbol_type) that)
@@ -622,6 +626,8 @@ m4_if(b4_prefix, [yy], [],
                                       [value], [move], [YY_MOVE 
(that.value)])],
                    [[value = YY_MOVE (that.value);]])[]b4_locations_if([
     location = YY_MOVE (that.location);])[
+    // that is emptied.
+    that.state = empty_state;
     return *this;
   }
 #endif
diff --git a/tests/c++.at b/tests/c++.at
index 2ce7b294..68167d09 100644
--- a/tests/c++.at
+++ b/tests/c++.at
@@ -162,19 +162,27 @@ int main()
     std::cerr << ss.value.as<int>() << '\n';
   }
 
-  // pushing on the stack.
+  // Pushing on the stack.
+  // Sufficiently many so that it will be resized.
+  // Probably 3 times (starting at 200).
   {
     parser::stack_type st;
-    for (int i = 0; i < 100; ++i)
+    const int mucho = 1700;
+    for (int i = 0; i < mucho; ++i)
       {
 #if defined __cplusplus && 201103L <= __cplusplus
-        st.push(parser::stack_symbol_type{1, parser::make_INT(123)});
+        st.push(parser::stack_symbol_type{1, parser::make_INT (i)});
 #else
-        parser::symbol_type s = parser::make_INT(123);
-        parser::stack_symbol_type ss(1, s);
-        st.push(ss);
+        parser::symbol_type s = parser::make_INT (i);
+        parser::stack_symbol_type ss (1, s);
+        st.push (ss);
 #endif
       }
+    for (int i = mucho - 1; 0 <= i; --i)
+      {
+        assert (st[0].value.as<int>() == i);
+        st.pop ();
+      }
   }
 }
 ]])




reply via email to

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