This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR lto/52178 (continued)
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 25 May 2012 12:27:50 +0200
- Subject: [patch] Fix PR lto/52178 (continued)
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.
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
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);