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.
This commit is contained in:
Akim Demaille
2018-10-18 07:07:32 +02:00
parent b994c3bf78
commit 3967e46a2d
2 changed files with 20 additions and 6 deletions

View File

@@ -602,6 +602,10 @@ m4_if(b4_prefix, [yy], [],
{]b4_variant_if([ {]b4_variant_if([
b4_symbol_variant([that.type_get ()], b4_symbol_variant([that.type_get ()],
[value], [YY_MOVE_OR_COPY], [YY_MOVE (that.value)])])[ [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) ]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], [move], [YY_MOVE (that.value)])],
[[value = YY_MOVE (that.value);]])[]b4_locations_if([ [[value = YY_MOVE (that.value);]])[]b4_locations_if([
location = YY_MOVE (that.location);])[ location = YY_MOVE (that.location);])[
// that is emptied.
that.state = empty_state;
return *this; return *this;
} }
#endif #endif

View File

@@ -162,19 +162,27 @@ int main()
std::cerr << ss.value.as<int>() << '\n'; 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; 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 #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 #else
parser::symbol_type s = parser::make_INT(123); parser::symbol_type s = parser::make_INT (i);
parser::stack_symbol_type ss(1, s); parser::stack_symbol_type ss (1, s);
st.push(ss); st.push (ss);
#endif #endif
} }
for (int i = mucho - 1; 0 <= i; --i)
{
assert (st[0].value.as<int>() == i);
st.pop ();
}
} }
} }
]]) ]])