mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
c++: fix double free when a symbol_type was moved
Currently the following piece of code crashes (with parse.assert),
because we don't record that s was moved-from, and we invoke its dtor.
{
auto s = parser::make_INT (42);
auto s2 = std::move (s);
}
Reported by Wolfgang Thaller.
http://lists.gnu.org/archive/html/bug-bison/2018-12/msg00077.html
* data/c++.m4 (by_type): Provide a move-ctor.
(basic_symbol): Be sure not to read a moved-from value.
* tests/c++.at (C++ Variant-based Symbols Unit Tests): Check this case.
This commit is contained in:
1
THANKS
1
THANKS
@@ -180,6 +180,7 @@ Wayne Green wayne@infosavvy.com
|
|||||||
Wei Song wsong83@gmail.com
|
Wei Song wsong83@gmail.com
|
||||||
Wojciech Polak polak@gnu.org
|
Wojciech Polak polak@gnu.org
|
||||||
Wolfgang S. Kechel wolfgang.kechel@prs.de
|
Wolfgang S. Kechel wolfgang.kechel@prs.de
|
||||||
|
Wolfgang Thaller wolfgang.thaller@gmx.net
|
||||||
Wolfram Wagner ww@mpi-sb.mpg.de
|
Wolfram Wagner ww@mpi-sb.mpg.de
|
||||||
Wwp subscript@free.fr
|
Wwp subscript@free.fr
|
||||||
xolodho xolodho@gmail.com
|
xolodho xolodho@gmail.com
|
||||||
|
|||||||
14
data/c++.m4
14
data/c++.m4
@@ -303,8 +303,8 @@ m4_define([b4_symbol_type_declare],
|
|||||||
/// Default constructor.
|
/// Default constructor.
|
||||||
by_type ();
|
by_type ();
|
||||||
|
|
||||||
/// Copy constructor.
|
/// Move or copy constructor.
|
||||||
by_type (const by_type& that);
|
by_type (YY_RVREF (by_type) that);
|
||||||
|
|
||||||
/// The symbol type as needed by the constructor.
|
/// The symbol type as needed by the constructor.
|
||||||
typedef token_type kind_type;
|
typedef token_type kind_type;
|
||||||
@@ -368,7 +368,7 @@ m4_define([b4_public_types_define],
|
|||||||
, value (]b4_variant_if([], [YY_MOVE (that.value)]))b4_locations_if([
|
, value (]b4_variant_if([], [YY_MOVE (that.value)]))b4_locations_if([
|
||||||
, location (YY_MOVE (that.location))])[
|
, location (YY_MOVE (that.location))])[
|
||||||
{]b4_variant_if([
|
{]b4_variant_if([
|
||||||
b4_symbol_variant([that.type_get ()], [value], [YY_MOVE_OR_COPY],
|
b4_symbol_variant([this->type_get ()], [value], [YY_MOVE_OR_COPY],
|
||||||
[YY_MOVE (that.value)])
|
[YY_MOVE (that.value)])
|
||||||
])[}
|
])[}
|
||||||
|
|
||||||
@@ -446,9 +446,17 @@ m4_define([b4_public_types_define],
|
|||||||
: type (empty_symbol)
|
: type (empty_symbol)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
#if 201103L <= YY_CPLUSPLUS
|
||||||
|
]b4_inline([$1])b4_parser_class_name[::by_type::by_type (by_type&& that)
|
||||||
|
: type (that.type)
|
||||||
|
{
|
||||||
|
that.clear ();
|
||||||
|
}
|
||||||
|
#else
|
||||||
]b4_inline([$1])b4_parser_class_name[::by_type::by_type (const by_type& that)
|
]b4_inline([$1])b4_parser_class_name[::by_type::by_type (const by_type& that)
|
||||||
: type (that.type)
|
: type (that.type)
|
||||||
{}
|
{}
|
||||||
|
#endif
|
||||||
|
|
||||||
]b4_inline([$1])b4_parser_class_name[::by_type::by_type (token_type t)
|
]b4_inline([$1])b4_parser_class_name[::by_type::by_type (token_type t)
|
||||||
: type (yytranslate_ (t))
|
: type (yytranslate_ (t))
|
||||||
|
|||||||
11
tests/c++.at
11
tests/c++.at
@@ -160,6 +160,17 @@ int main()
|
|||||||
assert_eq (s.value.as<int> (), 12);
|
assert_eq (s.value.as<int> (), 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// symbol_type: move constructor.
|
||||||
|
#if 201103L <= YY_CPLUSPLUS
|
||||||
|
{
|
||||||
|
auto s = parser::make_INT (42);
|
||||||
|
auto s2 = std::move (s);
|
||||||
|
assert_eq (s2.value.as<int> (), 42);
|
||||||
|
// Used to crash here, because s was improperly cleared, and
|
||||||
|
// its destructor tried to delete its (moved) value.
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// stack_symbol_type: construction, accessor.
|
// stack_symbol_type: construction, accessor.
|
||||||
{
|
{
|
||||||
#if 201103L <= YY_CPLUSPLUS
|
#if 201103L <= YY_CPLUSPLUS
|
||||||
|
|||||||
Reference in New Issue
Block a user