glr2.cc: fix pointer arithmethics

A glr_state keeps tracks of its predecessor using an offset relative
to itself (i.e., pointer subtraction).  Unfortunately we sometimes
have to compute offsets for pointers that live in different
containers, in particular in yyfillin.  In that case there is no
reason for the distance between the two objects to be a multiple of
the object size (0x40 on my machine), and the resulting ptrdiff_t may
be "wrong", i.e., it does allow to recover one from the other.  We
cannot use "typed" pointer arithmetics here, the Euclidean division
has it wrong.  So use "plain" char* pointers.

Fixes 718 (Duplicate representation of merged trees: glr2.cc) and
examples/c++/glr/c++-types.

Still XFAIL:

    712: Improper handling of embedded actions and dollar(-N) in GLR parsers: glr2.cc
    730: Incorrectly initialized location for empty right-hand side in GLR: glr2.cc
    748: Incorrect lookahead during nondeterministic GLR: glr2.cc

* data/skeletons/glr2.cc (glr_state::as_pointer_): New.
(glr_state::pred): Use it.
* examples/c++/glr/c++-types.test: The test passes.
* tests/glr-regression.at (Duplicate representation of merged trees:
glr2.cc): Passes.
This commit is contained in:
Akim Demaille
2020-12-06 16:35:21 +01:00
parent 2b52bd1644
commit 5b65b3d543
4 changed files with 14 additions and 6 deletions

View File

@@ -877,6 +877,14 @@ public:
static glr_stack_item* asItem(T* state) {
return reinterpret_cast<glr_stack_item*>(state);
}
static const char *as_pointer_ (const glr_state *state)
{
return reinterpret_cast<const char *>(state);
}
static char *as_pointer_ (glr_state *state)
{
return reinterpret_cast<char *>(state);
}
/** Preceding state in this stack */
std::ptrdiff_t yypred;
union {
@@ -1285,7 +1293,7 @@ glr_state* glr_state::pred ()
{]b4_parse_assert_if([[
check_ ();]])[
YY_IGNORE_NULL_DEREFERENCE_BEGIN
return yypred ? &(asItem (this) - yypred)->getState () : YY_NULLPTR;
return yypred ? &asItem (as_pointer_ (this) - yypred)->getState () : YY_NULLPTR;
YY_IGNORE_NULL_DEREFERENCE_END
}
@@ -1293,14 +1301,14 @@ const glr_state* glr_state::pred () const
{]b4_parse_assert_if([[
check_ ();]])[
YY_IGNORE_NULL_DEREFERENCE_BEGIN
return yypred ? &(asItem (this) - yypred)->getState () : YY_NULLPTR;
return yypred ? &asItem (as_pointer_ (this) - yypred)->getState () : YY_NULLPTR;
YY_IGNORE_NULL_DEREFERENCE_END
}
void glr_state::setPred (const glr_state* state)
{]b4_parse_assert_if([[
check_ ();]])[
yypred = state ? asItem(this) - asItem(state) : 0;
yypred = state ? as_pointer_ (this) - as_pointer_ (state) : 0;
}
semantic_option* glr_state::firstVal ()