On Tue, Oct 31, 2017 at 5:09 PM, David Malcolm <dmalc...@redhat.com> wrote:
> On Tue, 2017-10-24 at 09:53 -0400, Jason Merrill wrote:
>> On Fri, Oct 20, 2017 at 5:53 PM, David Malcolm <dmalc...@redhat.com>
>> wrote:
>> > Design questions:
>> >
>> > * The patch introduces a new kind of tree node, currently called
>> >   DECL_WRAPPER_EXPR (although it's used for wrapping constants as
>> > well
>> >   as decls).  Should wrappers be a new kind of tree node, or should
>> > they
>> >   reuse an existing TREE_CODE? (e.g. NOP_EXPR, CONVERT_EXPR, etc).
>> >     * NOP_EXPR: seems to be for use as an rvalue
>> >     * CONVERT_EXPR: for type conversions
>> >     * NON_LVALUE_EXPR: "Value is same as argument, but guaranteed
>> > not an
>> >       lvalue"
>> >       * but we *do* want to support lvalues here
>>
>> I think using NON_LVALUE_EXPR for constants would be appropriate.
>>
>> >     * VIEW_CONVERT_EXPR: viewing one thing as of a different type
>> >       * can it support lvalues?
>>
>> Yes, the purpose of VIEW_CONVERT_EXPR is to support lvalues, it seems
>> like the right choice.
>>
>> Jason
>
> Thanks.  I've been working on a new version of the patch using those
> tree codes, but have run into an issue.
>
> In g++.dg/conversion/reinterpret1.C:
>
>   // PR c++/15076
>
>   struct Y { Y(int &); };
>
>   int v;
>   Y y1(reinterpret_cast<int>(v));  // { dg-error "" }
>
> With trunk, this successfully generates an error:
>
>   reinterpret1.C:6:6: error: cannot bind non-const lvalue reference of type 
> ‘int&’ to an rvalue of type ‘int’
>    Y y1(reinterpret_cast<int>(v));  // { dg-error "" }
>         ^~~~~~~~~~~~~~~~~~~~~~~~
>   reinterpret1.C:3:12: note:   initializing argument 1 of ‘Y::Y(int&)’
>    struct Y { Y(int &); };
>               ^
>
> where internally there's a NON_LVALUE_EXPR around a VAR_DECL, where
> both have the same type:
>
> (gdb) call debug_tree (expr)
>  <non_lvalue_expr 0x7ffff145f6e0
>     type <integer_type 0x7ffff132e5e8 int public type_6 SI
>         size <integer_cst 0x7ffff1331120 constant 32>
>         unit-size <integer_cst 0x7ffff1331138 constant 4>
>         align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 
> 0x7ffff132e5e8 precision:32 min <integer_cst 0x7ffff13310d8 -2147483648> max 
> <integer_cst 0x7ffff13310f0 2147483647>
>         pointer_to_this <pointer_type 0x7ffff1336a80> reference_to_this 
> <reference_type 0x7ffff144ca80>>
>
>     arg:0 <var_decl 0x7ffff7ffbd80 v type <integer_type 0x7ffff132e5e8 int>
>         used public static tree_1 read SI 
> /home/david/coding-3/gcc-git-expr-vs-decl/src/gcc/testsuite/g++.dg/conversion/reinterpret1.C:5:5
>  size <integer_cst 0x7ffff1331120 32> unit-size <integer_cst 0x7ffff1331138 4>
>         align:32 warn_if_not_align:0 context <translation_unit_decl 
> 0x7ffff131e168 
> /home/david/coding-3/gcc-git-expr-vs-decl/src/gcc/testsuite/g++.dg/conversion/reinterpret1.C>
>         chain <type_decl 0x7ffff141a720 Y type <record_type 0x7ffff144c150 Y>
>             public decl_2 VOID 
> /home/david/coding-3/gcc-git-expr-vs-decl/src/gcc/testsuite/g++.dg/conversion/reinterpret1.C:3:8
>             align:8 warn_if_not_align:0 context <translation_unit_decl 
> 0x7ffff131e168 
> /home/david/coding-3/gcc-git-expr-vs-decl/src/gcc/testsuite/g++.dg/conversion/reinterpret1.C>
>  chain <function_decl 0x7ffff144f800 __cxa_call_unexpected>>>
>     
> /home/david/coding-3/gcc-git-expr-vs-decl/src/gcc/testsuite/g++.dg/conversion/reinterpret1.C:6:6
>  start: 
> /home/david/coding-3/gcc-git-expr-vs-decl/src/gcc/testsuite/g++.dg/conversion/reinterpret1.C:6:6
>  finish: 
> /home/david/coding-3/gcc-git-expr-vs-decl/src/gcc/testsuite/g++.dg/conversion/reinterpret1.C:6:29>
>
> The problem is that this reinterpret cast "looks" just like one of my
> location wrappers.

Your code shouldn't strip a NON_LVALUE_EXPR around a VAR_DECL.

> I see a similar issue with constants, where with:
>
>   struct Y { Y(int &); };
>   Y y1(reinterpret_cast<int>(42));
>
> trunk generates an error like the above, but my code handles the
>   NON_LVALUE_EXPR<int>(INTEGER_CST<int>(42))
> as if it were a location wrapper around the INTEGER_CST, and thus
> doesn't emit the error.

Why doesn't it emit the error?  We should get the same error whether
or not we strip the wrapper.

Jason

Reply via email to