------- Comment #4 from hubicka at gcc dot gnu dot org 2010-09-09 11:33 ------- testing the following fix: Index: class.c =================================================================== --- class.c (revision 163947) +++ class.c (working copy) @@ -7797,7 +7797,7 @@ build_vtbl_initializer (tree binfo, { fn = abort_fndecl; if (abort_fndecl_addr == NULL) - abort_fndecl_addr = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn); + fold_convert (vfunc_ptr_type_node, build_fold_addr_expr (fn)); init = abort_fndecl_addr; } else @@ -7810,7 +7810,7 @@ build_vtbl_initializer (tree binfo, } /* Take the address of the function, considering it to be of an appropriate generic type. */ - init = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn); + init = fold_convert (vfunc_ptr_type_node, build_fold_addr_expr (fn)); } this solves the ICE, but won't get call devirtualized. We end up with: MEM[(struct B *)&d]._vptr.B = &_ZTV1B[2]; d.D.2108._vptr.B = &_ZTV1D[2]; D.2210_2 = (int (*__vtbl_ptr_type) (void)) Run; OBJ_TYPE_REF(D.2210_2;&d.D.2108->0) (&d.D.2108); It seems that forw-prop should be told that OBJ_TYPE_REF does not care about nops on the operand and also fold_ccp can be told to call fold_obj_type_ref on the substituted constant. Martin, can you take a look, please?
I am attaching current WIP version of my constructor folding that makes D.2210_2 = (int (*__vtbl_ptr_type) (void)) Run; to happen. Honza -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45605