This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]