]> git.saurik.com Git - bison.git/blobdiff - data/lalr1-fusion.cc
Destroy the variants that remain on the stack in case of error.
[bison.git] / data / lalr1-fusion.cc
index 63bc1d5ab57e794cda41527259526e520da8ddab..20f1cb8cbc16f7ce834626fed38eb5a6e6c84a43 100644 (file)
@@ -40,6 +40,12 @@ b4_variant_if([
 ]) # b4_variant_if
 
 
+# b4_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT])
+# ----------------------------------------------------
+m4_define([b4_assert_if],
+[b4_percent_define_ifdef([[assert]], [$1], [$2])])
+
+
 # b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
 # --------------------------------------
 # Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
@@ -161,6 +167,7 @@ dnl FIXME: This is wrong, we want computed header guards.
 
 ]b4_percent_code_get([[requires]])[
 
+]b4_assert_if([#include <cassert>])[
 #include <string>
 #include <iostream>
 #include "stack.hh"
@@ -177,12 +184,22 @@ dnl FIXME: This is wrong, we want computed header guards.
   /// via the current state.
   template <size_t S>
   struct variant
-  {
+  {]b4_assert_if([
+    /// Whether something is contained.
+    bool built;
+
+    /// Initially uninitialized.
+    variant ()
+      : built(false)
+    {}])[
+
     /// Instantiate a \a T in here.
     template <typename T>
     inline T&
     build()
-    {
+    {]b4_assert_if([
+      assert(!built);
+      built = true;])[
       return *new (buffer) T;
     }
 
@@ -190,7 +207,8 @@ dnl FIXME: This is wrong, we want computed header guards.
     template <typename T>
     inline T&
     as()
-    {
+    {]b4_assert_if([
+      assert(built);])[
       return reinterpret_cast<T&>(buffer);
     }
 
@@ -198,7 +216,8 @@ dnl FIXME: This is wrong, we want computed header guards.
     template <typename T>
     inline const T&
     as() const
-    {
+    {]b4_assert_if([
+      assert(built);])[
       return reinterpret_cast<const T&>(buffer);
     }
 
@@ -218,6 +237,7 @@ dnl FIXME: This is wrong, we want computed header guards.
     {
       build<T>();
       swap<T>(other);
+      other.destroy<T>();
     }
 
     /// Destroy the stored \a T.
@@ -225,7 +245,8 @@ dnl FIXME: This is wrong, we want computed header guards.
     inline void
     destroy()
     {
-      as<T>().~T();
+      as<T>().~T();]b4_assert_if([
+      built = false;])[
     }
 
     /// A buffer large enough to store any of the semantic values.
@@ -429,6 +450,7 @@ m4_ifdef([b4_stype],
 
     /// \brief Reclaim the memory associated to a symbol.
     /// \param yymsg        Why this token is reclaimed.
+    ///                     If null, nothing is printed at all.
     /// \param yytype       The symbol type.
     /// \param yyvalue      Its semantic value.
     /// \param yylocation   Its location.
@@ -672,14 +694,19 @@ b4_percent_code_get[]dnl
     YYUSE (yyvalue);
     YYUSE (yylocation);
 
-    YY_SYMBOL_PRINT (yymsg, yytype, yyvalue, yylocation);
+    if (yymsg)
+      YY_SYMBOL_PRINT (yymsg, yytype, yyvalue, yylocation);
 
+    // User destructor.
     switch (yytype)
       {
   ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[
        default:
          break;
-      }
+      }]b4_variant_if([
+
+    // Type destructor.
+  b4_symbol_variant([[yytype]], [[yyvalue]], [[destroy]])])[
   }
 
   ]b4_parser_class_name[::data_type::data_type ()
@@ -905,16 +932,21 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
           break;
       }
     YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], yyval, yyloc);
-
-]b4_variant_if([
+]b4_variant_if([[
     // Destroy the lhs symbols.
     for (int i = 0; i < yylen; ++i)
-      {
-        b4_symbol_variant([[yystos_[yystack_@{i@}.state]]],
-                          [[yystack_@{i@}.value]],
-                          [[destroy]])
-      }])dnl
-[
+      // Destroy a variant which value may have be swapped with yyval.
+      // The value of yyval (hence maybe one of these lhs symbols)
+      // depends on what does the default contruction for this type.
+      // In the case of pointers for instance, nothing is done, so the
+      // value is junk.  Therefore do not try to report the content in
+      // the debug trace, it's junk.  Hence yymsg = 0.  Besides, that
+      // keeps exactly the same traces as with the other Bison
+      // skeletons.
+      yydestruct_ (0,
+                   yystos_[yystack_[i].state],
+                   yystack_[i].value, yystack_[i].location);]])[
+
     yypop_ (yylen);
     yylen = 0;
     YY_STACK_PRINT ();