[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FYI: master: c++: variant: add more assertions
From: |
Akim Demaille |
Subject: |
FYI: master: c++: variant: add more assertions |
Date: |
Sat, 11 Aug 2018 18:37:26 +0200 |
The example given by Piotr in
http://lists.gnu.org/archive/html/bug-bison/2017-06/msg00000.html
will actually crash if parse.assert is enabled. It does show
that something very rotten was going on, but an abort is better
than a SEGV :)
To reproduce the error, try with the attached grammar.
bar.yy
Description: Binary data
This shows that we should forbid the use of ‘$<foo>’ when using
(Bison) variants: the corresponding symbol was not even constructed,
because, since Bison does not know that $2 is an integer, it cannot
build the symbol before handing it over to the user action. To see
that, have a look at the generated code:
> yyreduce:
> yylen = yyr2_[yyn];
> {
> stack_symbol_type yylhs;
> yylhs.state = yy_lr_goto_state_ (yystack_[yylen].state, yyr1_[yyn]);
> /* Variants are always initialized to an empty instance of the
> correct type. The default '$$ = $1' action is NOT applied
> when using variants. */
> switch (yyr1_[yyn])
> {
> case 3: // NUMBER
> case 5: // expr
> yylhs.value.build< int > ();
> break;
>
> default:
> break;
> }
>
> // Perform the reduction.
> YY_REDUCE_PRINT (yyn);
> try
> {
> switch (yyn)
> {
> case 2:
> #line 27 "bar.yy" // lalr1.cc:856
> { yylhs.value.as< int > () = yystack_[0].value.as< int > () * 10; }
> #line 527 "bar.tab.cc" // lalr1.cc:856
> break;
>
> case 3:
> #line 28 "bar.yy" // lalr1.cc:856
> { yylhs.value.as< int > () = 20; }
> #line 533 "bar.tab.cc" // lalr1.cc:856
> break;
>
> case 4:
> #line 29 "bar.yy" // lalr1.cc:856
> {
> std::cerr << "expr: "
> << yystack_[2].value.as< int > () << ' '
> << yystack_[1].value.as< int > () << ' '
> << yystack_[0].value.as< int > () << '\n';
> yylhs.value.as< int > () = 40;
> }
> #line 542 "bar.tab.cc" // lalr1.cc:856
> break;
>
>
> #line 546 "bar.tab.cc" // lalr1.cc:856
> default:
> break;
> }
> }
> catch (const syntax_error& yyexc)
> {
> error (yyexc);
> YYERROR;
> }
> YY_SYMBOL_PRINT ("-> $$ =", yylhs);
> yypop_ (yylen);
> yylen = 0;
> YY_STACK_PRINT ();
>
> // Shift the result of the reduction.
> yypush_ (YY_NULLPTR, yylhs);
> }
> goto yynewstate;
When using a typed midrule, it works properly.
commit 4410084223ae6ea7c0d4808599786078d83fac0b
Author: Akim Demaille <address@hidden>
Date: Thu Aug 9 07:33:23 2018 +0200
c++: variant: add more assertions
* data/variant.hh (variant::as): Check yytypeid_ before
checking *yytypeid_.
diff --git a/data/variant.hh b/data/variant.hh
index 7a6fbfb9..41ed84ab 100644
--- a/data/variant.hh
+++ b/data/variant.hh
@@ -140,6 +140,7 @@ m4_define([b4_variant_define],
T&
as ()
{]b4_parse_assert_if([
+ YYASSERT (yytypeid_);
YYASSERT (*yytypeid_ == typeid (T));
YYASSERT (sizeof (T) <= S);])[
return *yyas_<T> ();
@@ -150,6 +151,7 @@ m4_define([b4_variant_define],
const T&
as () const
{]b4_parse_assert_if([
+ YYASSERT (yytypeid_);
YYASSERT (*yytypeid_ == typeid (T));
YYASSERT (sizeof (T) <= S);])[
return *yyas_<T> ();
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- FYI: master: c++: variant: add more assertions,
Akim Demaille <=