glr2.cc: beware of self-assignment

In yycompressStack:

    while (yyr != YY_NULLPTR)
      {
        nextFreeItem->check_ ();
        yyr->check_();
        nextFreeItem->setState(*yyr);
        glr_state& nextFreeState = nextFreeItem->getState();
        yyr = yyr->pred();
        nextFreeState.setPred(&(nextFreeItem - 1)->getState());
        setFirstTop(&nextFreeState);
        ++nextFreeItem;
      }

it is possible that nextFreeItem and yyr are actually the same state.
In which case `nextFreeItem->setState(*yyr)` does really bad things.

* data/skeletons/glr2.cc (glr_stack_item::setState): Beware of
self-assignment.
This commit is contained in:
Akim Demaille
2020-12-25 08:53:31 +01:00
parent 7dc942dca3
commit 636c9a8042

View File

@@ -896,6 +896,12 @@ public:
return asItem(this); return asItem(this);
} }
const glr_stack_item* asItem () const
{]b4_parse_assert_if([[
check_ ();]])[
return asItem (this);
}
private: private:
template <typename T> template <typename T>
static const glr_stack_item* asItem (const T* state) static const glr_stack_item* asItem (const T* state)
@@ -1272,12 +1278,15 @@ public:
{]b4_parse_assert_if([[ {]b4_parse_assert_if([[
check_ (); check_ ();
state.check_ ();]])[ state.check_ ();]])[
// FIXME: What about the previous content? Shouldn't it be freed? if (this != state.asItem ())
// It might be useful to have an explicit "void" state when this item {
// is in unused state (in the list of free items), when parse.assert is_state_ = true;
// is set. // FIXME: What about the previous content? Shouldn't it be
is_state_ = true; // freed? It might be useful to have an explicit "void" state
new (&raw_) glr_state (state); // when this item is in unused state (in the list of free
// items), when parse.assert is set.
new (&raw_) glr_state (state);
}
} }
glr_state& getState () glr_state& getState ()