summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2018-12-23 19:37:30 +0100
committerAkim Demaille <akim.demaille@gmail.com>2018-12-24 18:58:56 +0100
commit807bf60cfc08dda89e81b171d8667a6a491afe26 (patch)
tree9c9e0684dd4d68d4cdf0f0f46b638317893f0401
parent45cd7dfb7f9d7875c1ba86663f601920d6a7b69f (diff)
downloadbison-807bf60cfc08dda89e81b171d8667a6a491afe26.tar.gz
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.
-rw-r--r--THANKS1
-rw-r--r--data/c++.m414
-rw-r--r--tests/c++.at11
3 files changed, 23 insertions, 3 deletions
diff --git a/THANKS b/THANKS
index cb0c5737..86c23eef 100644
--- a/THANKS
+++ b/THANKS
@@ -180,6 +180,7 @@ Wayne Green wayne@infosavvy.com
Wei Song wsong83@gmail.com
Wojciech Polak polak@gnu.org
Wolfgang S. Kechel wolfgang.kechel@prs.de
+Wolfgang Thaller wolfgang.thaller@gmx.net
Wolfram Wagner ww@mpi-sb.mpg.de
Wwp subscript@free.fr
xolodho xolodho@gmail.com
diff --git a/data/c++.m4 b/data/c++.m4
index 1234caa3..3dea30a4 100644
--- a/data/c++.m4
+++ b/data/c++.m4
@@ -303,8 +303,8 @@ m4_define([b4_symbol_type_declare],
/// Default constructor.
by_type ();
- /// Copy constructor.
- by_type (const by_type& that);
+ /// Move or copy constructor.
+ by_type (YY_RVREF (by_type) that);
/// The symbol type as needed by the constructor.
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([
, location (YY_MOVE (that.location))])[
{]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)])
])[}
@@ -446,9 +446,17 @@ m4_define([b4_public_types_define],
: 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)
: type (that.type)
{}
+#endif
]b4_inline([$1])b4_parser_class_name[::by_type::by_type (token_type t)
: type (yytranslate_ (t))
diff --git a/tests/c++.at b/tests/c++.at
index 823b5f3c..8be85b8a 100644
--- a/tests/c++.at
+++ b/tests/c++.at
@@ -160,6 +160,17 @@ int main()
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.
{
#if 201103L <= YY_CPLUSPLUS