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);
}
const glr_stack_item* asItem () const
{]b4_parse_assert_if([[
check_ ();]])[
return asItem (this);
}
private:
template <typename T>
static const glr_stack_item* asItem (const T* state)
@@ -1272,12 +1278,15 @@ public:
{]b4_parse_assert_if([[
check_ ();
state.check_ ();]])[
// FIXME: What about the previous content? Shouldn't it be freed?
// 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 set.
is_state_ = true;
new (&raw_) glr_state (state);
if (this != state.asItem ())
{
is_state_ = true;
// FIXME: What about the previous content? Shouldn't it be
// freed? 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 set.
new (&raw_) glr_state (state);
}
}
glr_state& getState ()