------- Comment #7 from jakub at gcc dot gnu dot org 2008-01-04 15:17 ------- This is a problem during inlining. The call actually has &optab_table argument: <addr_expr 0x2aaaae9035c0 type <pointer_type 0x2aaaaea1e600 type <record_type 0x2aaaaea1e300 optab type_0 SI ... > ...> arg 0 <var_decl 0x2aaaae9e8280 optab_table type <array_type 0x2aaaaea1ef00 type <record_type 0x2aaaaea1ecc0 optab> ... > and two different optab RECORD_TYPEs are involved (one from each CU). These types are types_compatible_p (0x2aaaaea1e300, 0x2aaaaea1ecc0), but not are not equal. copy_body_r calls 699 *tp = fold_indirect_ref_1 (type, new); 700 if (! *tp) 701 { 702 if (TREE_CODE (new) == ADDR_EXPR) 703 *tp = TREE_OPERAND (new, 0); here, but as the /* *(foo *)&fooarray => fooarray[0] */ transformation is done only if the types are equal, this isn't folded into &optab_table[0] and so inlining creates optab_table.code COMPONENT_REF, where its first argument is not a record/union/qual union. Either we change fold_indirect_ref_1 to do its transformations whenever types_compatible_p (type1, type2) rather than just type1 == type2, or if that's too expensive IMHO at least copy_body_r should do that.
-- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34668