Message ID | 201205251227.50761.ebotcazou@adacore.com |
---|---|
State | New |
Headers | show |
On Fri, May 25, 2012 at 12:27 PM, Eric Botcazou <ebotcazou@adacore.com> wrote: > This is a follow-up to PR lto/52178: there are more "type mismatch in component > reference" issues related to variably_modified_type_p when you try to build > the gnattools with -flto: > > 1. Instances of a record type with fixed size at top level aren't merged if > it has a field with self-referential size because variably_modified_type_p > returns true for the latter. I think the fix is straightforward: return > false for the special PLACEHOLDER_EXPR marker that is set in this case by > free_lang_data_in_one_sizepos. > > 2. Twin variably_modified_type_p qualified union types that belong to two > different functions may appear in the same COMPONENT_REF expression, > leading to a type mismatch. This occurs after a variably_modified_type_p > qualified union in the first function is remapped during the versioning > done by ipa-split to create the second function, and remapping overwrites > the type of a FIELD_DECL of the original type. > > Proposed patch attached, bootstrapped/regtested on x86_64-suse-linux and LTO > bootstrapped on the same platform. #1 is a regression from 4.6 and #2 has > been exposed by ipa-split (although it's probably older) so I'd like to put > this on the 4.7 branch as well. Ok. Please make sure to verify LTO bootstrap on the branch still works after this. Thanks, Richard. > > 2012-05-25 Eric Botcazou <ebotcazou@adacore.com> > > PR lto/52178 > * tree-inline.c (remap_gimple_op_r): Fix handling of FIELD_DECL. > * tree.c (RETURN_TRUE_IF_VAR): Do not return true for PLACEHOLDER_EXPR. > > > -- > Eric Botcazou
> Ok. Please make sure to verify LTO bootstrap on the branch still > works after this. Thanks. I already verified it with --enable-checking=yes,rtl.
Index: tree.c =================================================================== --- tree.c (revision 187868) +++ tree.c (working copy) @@ -8477,8 +8477,11 @@ variably_modified_type_p (tree type, tre a variable in FN. */ #define RETURN_TRUE_IF_VAR(T) \ do { tree _t = (T); \ - if (_t && _t != error_mark_node && TREE_CODE (_t) != INTEGER_CST \ - && (!fn || walk_tree (&_t, find_var_from_fn, fn, NULL))) \ + if (_t != NULL_TREE \ + && _t != error_mark_node \ + && TREE_CODE (_t) != INTEGER_CST \ + && TREE_CODE (_t) != PLACEHOLDER_EXPR \ + && (!fn || walk_tree (&_t, find_var_from_fn, fn, NULL))) \ return true; } while (0) if (type == error_mark_node) Index: tree-inline.c =================================================================== --- tree-inline.c (revision 187868) +++ tree-inline.c (working copy) @@ -818,6 +818,15 @@ remap_gimple_op_r (tree *tp, int *walk_s || decl_function_context (*tp) == id->src_fn)) /* These may need to be remapped for EH handling. */ *tp = remap_decl (*tp, id); + else if (TREE_CODE (*tp) == FIELD_DECL) + { + /* If the enclosing record type is variably_modified_type_p, the field + has already been remapped. Otherwise, it need not be. */ + tree *n = (tree *) pointer_map_contains (id->decl_map, *tp); + if (n) + *tp = *n; + *walk_subtrees = 0; + } else if (TYPE_P (*tp)) /* Types may need remapping as well. */ *tp = remap_type (*tp, id);