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:16:47 -0400

HI

Also

http://lists.gnu.org/archive/html/bug-bison/2015-01/msg00066.html

seems indicated bison does not support std::unique_ptr as a semantic values


min




On Thu, Aug 18, 2016 at 3:05 PM, Min Wang <address@hidden> wrote:

> 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
>
>
>
>


-- 
http://www.comrite.com


reply via email to

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