From: Akim Demaille Date: Wed, 19 Dec 2012 09:18:03 +0000 (+0100) Subject: variants: prohibit simple copies X-Git-Tag: v2.7.90~241 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/7be08dfbe7efc259a4d11c320e85ffbec494a45f variants: prohibit simple copies The "variant" structure provides a means to store, in a typeless way, C++ objects. Manipulating it without provide the type of the stored content is doomed to failure. So provide a means to copy in a type safe way, and prohibit typeless assignments. * data/c++.m4 (symbol_type::move): New. * data/lalr1.cc: Use it. * data/variant.hh (b4_variant_define): Provide variant::copy. Let variant::operator= abort. We cannot undefine it, yet, as it is still uses by the implicit assigment in symbols, which must also be disabled. --- diff --git a/data/c++.m4 b/data/c++.m4 index 10855df9..66982de4 100644 --- a/data/c++.m4 +++ b/data/c++.m4 @@ -185,6 +185,9 @@ m4_define([b4_public_types_declare], /// Default constructor. inline symbol_type (); + /// Destructive move, \a s is emptied. + inline void move (symbol_type& s); + /// Constructor for tokens with semantic value. inline symbol_type (]b4_join([token_type t], [const semantic_type& v], @@ -294,6 +297,16 @@ m4_define([b4_public_types_define], { } + inline + void + ]b4_parser_class_name[::symbol_type::move (symbol_type& s) + { + ]b4_variant_if([b4_symbol_variant([[s.type]], [value], [build], [s.value])], + [value = s.value;])[ + type = s.type;]b4_locations_if([ + location = s.location;])[ + } + inline int ]b4_parser_class_name[::symbol_type::type_get_ () const diff --git a/data/lalr1.cc b/data/lalr1.cc index 0209925d..53000bae 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -721,10 +721,11 @@ b4_dollar_popdef])[]dnl try { ]b4_token_ctor_if( -[ yyla = b4_function_call([yylex], [symbol_type], - m4_ifdef([b4_lex_param], b4_lex_param));], -[ yyla.type = yytranslate_ (b4_function_call([yylex], [int], - [b4_api_PREFIX[STYPE*], [&yyla.value]][]dnl +[ symbol_type yylookahead = b4_function_call([yylex], [symbol_type], + m4_ifdef([b4_lex_param], b4_lex_param)); + yyla.move(yylookahead);], +[ yyla.type = yytranslate_ (b4_function_call([yylex], [int], + [b4_api_PREFIX[STYPE*], [&yyla.value]][]dnl b4_locations_if([, [[location*], [&yyla.location]]])dnl m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[ } diff --git a/data/variant.hh b/data/variant.hh index 684f9e35..454f360a 100644 --- a/data/variant.hh +++ b/data/variant.hh @@ -79,6 +79,7 @@ m4_map([b4_char_sizeof_], [$@])dnl # The needed includes for variants support. m4_define([b4_variant_includes], [b4_parse_assert_if([[#include ]])[ +#include // abort #ifndef YYASSERT # include # define YYASSERT assert @@ -188,6 +189,15 @@ m4_define([b4_variant_define], other.destroy(); } + /// Copy the content of \a other to this. + /// Destroys \a other. + template + inline void + copy (const variant& other) + { + build (other.as ()); + } + /// Destroy the stored \a T. template inline void @@ -198,6 +208,13 @@ m4_define([b4_variant_define], tname = YY_NULL;])[ } + /// Prohibit blind copies. + // private: + self_type& operator=(const self_type&) + { + abort (); + } + private: /// A buffer large enough to store any of the semantic values. /// Long double is chosen as it has the strongest alignment