The following testcase taken from testsuite (and many others):
// PR 14535
// { dg-do run }
// { dg-options "-O -finline" }
// Original test case failure required that Raiser constructor be inlined.

extern "C" void abort(); 
bool destructor_called = false; 

struct B { 
    virtual void Run(){}; 

struct D : public B { 
    virtual void Run() 
        struct O { 
            ~O() { destructor_called = true; }; 
        } o; 

        struct Raiser { 
            Raiser()  throw( int ) {throw 1;}; 
        } raiser; 

int main() { 
    try { 
      D d; 
    } catch (...) {} 

    if (!destructor_called) 
      abort (); 

leads to following in .optimized dump:
<bb 2>:
  MEM[(struct B *)&d]._vptr.B = &_ZTV1B[2];
  d.D.2108._vptr.B = &_ZTV1D[2];
  D.2210_2 = _ZTV1D[2];
  OBJ_TYPE_REF(D.2210_2;&d.D.2108->0) (&d.D.2108);

Obviously OBJ_TYPE_REF can be optimized here since we know the
virtual table.  Why it is missed?

I run into it because my new folding code is actually smart enough to lead to:
int (*__vtbl_ptr_type) (void)

void D::<T400> (struct D *)

D.2210_2 = Run;

The error comes because we pick from initializer of VTBL the following
 <addr_expr 0x7ffff7ec8b10
    type <pointer_type 0x7ffff6b7db28 __vtbl_ptr_type
        type <function_type 0x7ffff6b7da80 type <integer_type 0x7ffff7edb498
            type_6 QI
            size <integer_cst 0x7ffff7ec54d8 constant 8>
            unit size <integer_cst 0x7ffff7ec5500 constant 1>
            align 8 symtab 0 alias set -1 canonical type 0x7ffff6b7da80
            pointer_to_this <pointer_type 0x7ffff6b7db28 __vtbl_ptr_type>>
        unsigned type_6 DI
        size <integer_cst 0x7ffff7ec57d0 constant 64>
        unit size <integer_cst 0x7ffff7ec57f8 constant 8>
        align 64 symtab 0 alias set -1 canonical type 0x7ffff6b7db28
        pointer_to_this <pointer_type 0x7ffff6b7dc78>>
    arg 0 <function_decl 0x7ffff6b8e500 Run
        type <method_type 0x7ffff6b9b9d8 type <void_type 0x7ffff7edbe70 void>
            type_6 QI size <integer_cst 0x7ffff7ec54d8 8> unit size
<integer_cst 0x7ffff7ec5500 1>
            align 8 symtab 0 alias set -1 canonical type 0x7ffff6b9b9d8 method
basetype <record_type 0x7ffff6b9b7e0 D>
            arg-types <tree_list 0x7ffff6b80af0 value <pointer_type
                chain <tree_list 0x7ffff7eed398 value <void_type 0x7ffff7edbe70
            pointer_to_this <pointer_type 0x7ffff6bab150>>
        addressable volatile asm_written used public static weak autoinline
virtual decl_5 QI file /home/jh/a.C line 15 col 18 align 16 context
<record_type 0x7ffff6b9b7e0 D> initial <error_mark 0x7ffff7ecdb28>
        arguments <parm_decl 0x7ffff7ece990 this type <pointer_type
            readonly unsigned DI file /home/jh/a.C line 15 col 22 size
<integer_cst 0x7ffff7ec57d0 64> unit size <integer_cst 0x7ffff7ec57f8 8>
            align 64 context <function_decl 0x7ffff6b8e500 Run>
            (reg/f:DI 62 [ this ]) arg-type <pointer_type 0x7ffff6b9bb28>
            incoming-rtl (reg:DI 5 di [ this ])>
        result <result_decl 0x7ffff7ed0380 D.2112 type <void_type
0x7ffff7edbe70 void>
            ignored VOID file /home/jh/a.C line 16 col 7
            align 8 context <function_decl 0x7ffff6b8e500 Run>>
        full-name "virtual void D::Run()"
        pending-inline-info 0x7ffff6ba42a0
        (mem:QI (symbol_ref/i:DI ("_ZN1D3RunEv") [flags 0x1] <function_decl
0x7ffff6b8e500 Run>) [0 S1 A8])>>

Note the differece in between type of address and the method RUN.  This is what
makes verifier unhappy.  How to fix this?  Should FE put there some NOP_EXPR
somewhere? Still devirtualizing should realize this case a lot earlier.


           Summary: Missed devirtualization
           Product: gcc
           Version: 4.6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: hubicka at gcc dot gnu dot org

Reply via email to