> 
> ICK.  Can you please solve the C++ issue differently?  The patch
> also seems to do many other things ...

If you refer to the fact that C++ seem to create non-ODR types that are
structurally equivalent to ODR types, i tracked it down.  Testcase is
testsuite/g++.dg/lto/20080904_0.C
compiled with -O0 -flto. Then we get structural match of:

truct Base

struct 
{
  int (*__vtbl_ptr_type) () * _vptr.Base;
  char * _buf;
  unsigned int _len;
}

More precisely:

 <record_type 0x7ffff6963a80 Base addressable cxx-odr-p type_1 type_5 type_6 BLK
    size <integer_cst 0x7ffff682d2e8 type <integer_type 0x7ffff68290a8 
bitsizetype> constant 192>
    unit-size <integer_cst 0x7ffff682d2b8 type <integer_type 0x7ffff6829000 
sizetype> constant 24>
    align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 
0x7ffff6963a80
    fields <field_decl 0x7ffff6930980 _vptr.Base
        type <pointer_type 0x7ffff6963540 type <pointer_type 0x7ffff69631f8 
__vtbl_ptr_type>
            unsigned DI
            size <integer_cst 0x7ffff680ce28 constant 64>
            unit-size <integer_cst 0x7ffff680ce40 constant 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 
0x7ffff6963540>
        unsigned virtual DI a.C:5:7 size <integer_cst 0x7ffff680ce28 64> 
unit-size <integer_cst 0x7ffff680ce40 8>
        align:64 warn_if_not_align:0 offset_align 128
        offset <integer_cst 0x7ffff680ce58 constant 0>
        bit-offset <integer_cst 0x7ffff680cea0 constant 0> context <record_type 
0x7ffff6963a80 Base>
        chain <field_decl 0x7ffff6930850 _buf type <pointer_type 0x7ffff6834e70>
            used private unsigned nonlocal decl_3 DI a.C:15:10 size 
<integer_cst 0x7ffff680ce28 64> unit-size <integer_cst 0x7ffff680ce40 8>
            align:64 warn_if_not_align:0 offset_align 128 offset <integer_cst 
0x7ffff680ce58 0> bit-offset <integer_cst 0x7ffff680ce28 64> context 
<record_type 0x7ffff6963a80 Base> chain <field_decl 0x7ffff69308e8 _len>>> 
context <translation_unit_decl 0x7ffff6819168 a.C>
    pointer_to_this <pointer_type 0x7ffff6978150> reference_to_this 
<reference_type 0x7ffff69815e8>>

 <record_type 0x7ffff69783f0 BLK
    size <integer_cst 0x7ffff69741c8 type <integer_type 0x7ffff68290a8 
bitsizetype> constant 160>
    unit-size <integer_cst 0x7ffff69741f8 type <integer_type 0x7ffff6829000 
sizetype> constant 20>
    align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 
0x7ffff69783f0
    fields <field_decl 0x7ffff6930a18 _vptr.Base
        type <pointer_type 0x7ffff6963540 type <pointer_type 0x7ffff69631f8 
__vtbl_ptr_type>
            unsigned DI
            size <integer_cst 0x7ffff680ce28 constant 64>
            unit-size <integer_cst 0x7ffff680ce40 constant 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 
0x7ffff6963540>
        unsigned virtual DI a.C:5:7 size <integer_cst 0x7ffff680ce28 64> 
unit-size <integer_cst 0x7ffff680ce40 8>
        align:64 warn_if_not_align:0 offset_align 128
        offset <integer_cst 0x7ffff680ce58 constant 0>
        bit-offset <integer_cst 0x7ffff680cea0 constant 0> context <record_type 
0x7ffff69783f0>
        chain <field_decl 0x7ffff6930ab0 _buf type <pointer_type 0x7ffff6834e70>
            private unsigned nonlocal decl_3 DI a.C:15:10 size <integer_cst 
0x7ffff680ce28 64> unit-size <integer_cst 0x7ffff680ce40 8>
            align:64 warn_if_not_align:0 offset_align 128 offset <integer_cst 
0x7ffff680ce58 0> bit-offset <integer_cst 0x7ffff680ce28 64> context 
<record_type 0x7ffff69783f0> chain <field_decl 0x7ffff6930b48 _len>>> context 
<record_type 0x7ffff6963a80 Base> reference_to_this <reference_type 
0x7ffff69789d8>>

which differ by nothing except of TYPE_NAME and TYPE_SIZE.
They are created here.

  if (CLASSTYPE_NON_LAYOUT_POD_P (t) || CLASSTYPE_EMPTY_P (t))
    {
      /* T needs a different layout as a base (eliding virtual bases
         or whatever).  Create that version.  */
      tree base_t = make_node (TREE_CODE (t));

which makes sense I suppose, but confuses ODR logic and also goes odd
way through canonical type calculations. In non-LTO alias sets are same
because C++ FE does:

31      cxx_get_alias_set (tree t)
32      {
33        if (IS_FAKE_BASE_TYPE (t))
34          /* The base variant of a type must be in the same alias set
as the
35             complete type.  */
36          return get_alias_set (TYPE_CONTEXT (t));

I am not quite sure why it is not simply copying the TYPE_CANONICAL
when the type is created instead.

In LTO I think they may end up with different canonical types and later
alias sets because they may have different virtual bases.

I am not sure why this does not seem to reak with TBAA, but will try to
get testcase where both types are structurally different (and do not
differ only by size). Perhaps we want to expose IS_FAKE_BASE to middle
end to get things working more reasonably.

Honza

Reply via email to