bug-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bison 3.0.4 %destructor is c++ mode seems to be called even in the n


From: Min Wang
Subject: Re: bison 3.0.4 %destructor is c++ mode seems to be called even in the normal parse
Date: Thu, 18 Aug 2016 15:05:08 -0400

HI
@kaz. thanks. I will check the %union later

I'like to use the smart pointers ( std::unique_ptr) , but somehow I got
some compiler errors.

here are some details:
e.g:

using PROG_PTR = std::unique_ptr<PROG>;
....


%type <PROG_PTR> PROG

%type <ListExp_PTR> ListExp

%type <Exp_PTR> Exp

...


PROG : ListExp      {
                   std::reverse( $1->begin(), $1->end() );
                   // store the result to filter_driver.prog
                   driver.store_ast( new Json_Filter( std::move($1) ) );
                   }
;

ListExp : Exp    {
                         ListExp_PTR tmp( new ListExp() ) ;
                         tmp->push_back( std::move($1) );
                         std::swap( $$, tmp );
                       }

//some classes

class PROG : public Visitable

{

public:

    virtual ~PROG() {};



};

// real one here

using ListExp_PTR = std::unique_ptr<ListExp>;



class Json_Filter : public PROG

{

public:

  ListExp_PTR listexp_;



  Json_Filter(ListExp_PTR p1) : listexp_( std::move(p1) ) {}

  ~Json_Filter() {}



};

// should not inherit vector here, put here just for testing now.
class ListExp : public Visitable, public std::vector<Exp_PTR>

{

public:

};



but I got those errors:
....

In file included from filter_parser.cpp:46:0:

filter_parser.hh: In instantiation of ‘T&
brc_filter::variant<S>::build(const T&) [with T = std::unique_ptr<ListExp>;
long unsigned int S = 8ul]’:
filter_parser.hh:241:12:   required from ‘void
brc_filter::variant<S>::copy(const self_type&) [with T =
std::unique_ptr<ListExp>; long unsigned int S = 8ul;
brc_filter::variant<S>::self_type = brc_filter::variant<8ul>]’
filter_parser.cpp:353:46:   required from here

filter_parser.hh:184:37: error: use of deleted function
‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&)
[with _Tp = ListExp; _Dp = std::default_delete<ListExp>]’
       return *new (yyas_<T> ()) T (t);

                                     ^

In file included from /usr/include/c++/4.9/memory:81:0,

                 from syntax.hh:6,

                 from filter_parser.yy:46,

                 from filter_parser.cpp:46:

/usr/include/c++/4.9/bits/unique_ptr.h:356:7: note: declared here

       unique_ptr(const unique_ptr&) = delete;

....

the filter_parser.hh:184  is:

    /// Instantiate a \a T in here from \a t.

    template <typename T>

    T&

    build (const T& t)

    {

      YYASSERT (!yytypeid_);

      YYASSERT (sizeof (T) <= S);

      yytypeid_ = & typeid (T);

      return *new (yyas_<T> ()) T (t);

    }


seems the build function somehow is not right?


thanks


min

On Thu, Aug 18, 2016 at 1:12 PM, Kaz Kylheku <address@hidden> wrote:

> On 18.08.2016 08:36, Min Wang wrote:
>
>> HI
>>
>> In bison 3.0.4, the  %destructor seems to be called even in the normal
>> parse
>>
>
> In your example program you are using "Variants" rather
> than %union. That's a very special C++-specific Bison feature.
>
> It seems that there is no reason to use %destructor if you're
> using variants. If any of the variants are pointers, they can
> just be smart pointers; they don't have to be low level pointers.
>
> Can you confirm whether %destructor is still called in the
> normal parse if instead of:
>
>   %type <PROG*> PROG
>   %type <ListExp*> ListExp
>
> you use
>
>   %union {
>     PROG *PROG;
>     ListExp *ListExp;
>   }
>
> That is to say, is this a issue specific to variants, or does it
> affect C++ parsers regardless of whether %union or variants
> are used?
>
> If under %union, %destructor is correctly called only during
> error recovery (the issue is absent) then just use %union,
> since all your semantic value types are pointers. Then be sure
> you have all the right delete calls in your grammar actions.
>
> If you use variants, it seems you can side-step the issue
> by not using pointers. If the values are smart pointers,
> then there is no problem, because a rule like:
>
>    foo : bar { $$ = $1; }
>
> will handle the transfer from $1 to $$ using the smart pointer
> assignment operator, allowing $1 to then be safely destroyed
> by its destructor.
>
> It does seem that you have discovered at least this bug,
> or deviation from documented behavior: when plain pointer types
> are used in variant declarations in a C++ parser, and %destructor
> is used to free them in all circumstances.
>
> So for instance, suppose that we use the type <char *>,
> and we have a %destructor which calls free. In a C parser,
> we might just have this:
>
>    foo : bar { $$ = $1; }  /* transfer ownership of pointer */
>
> But under C++ Bison with variants, we must do:
>
>    foo : bar { $$ = strdup($1); } /* $1 %destructor will kick in */
>
> Or perhaps this will work:
>
>    foo : bar { $$ = $1;
>                $1 = NULL; } /* Spare $1 from jaws of %destructor */
>
>
>
>


-- 
http://www.comrite.com


reply via email to

[Prev in Thread] Current Thread [Next in Thread]