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