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 PR51567


This fixes PR51567 - we are incorrectly merging the two 'iterator'
types in

class _Deque_base {
public:
    typedef _Deque_iterator iterator;
    iterator _M_impl;
};
class deque : public _Deque_base {
public:
    typedef _Deque_base::iterator iterator;
};

which results in dwarf2out.c being confused.  The following patch
fixes that, which results in SPEC 2k6 to build fine with LTO and
debug info enabled (finally!).

LTO bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

I'll apply this once the testing finished.

Honza, now is a good time to test if Mozilla is happy with -flto -g
(and maybe also watch how (bad) memory usage and diskspace usage got).

Thanks,
Richard.

2011-12-15  Richard Guenther  <rguenther@suse.de>

	PR lto/51567
	* gimple.c (compare_type_names_p): Also compare the TREE_CODE.
	(iterative_hash_name): Also hash the TREE_CODE.
	(gimple_types_compatible_p_1): For types with a TYPE_DECL
	name and a type DECL_CONTEXT recurse to that type.
	(iterative_hash_gimple_type): Likewise.

	* g++.dg/lto/pr51567-1_0.C: New testcase.

Index: gcc/gimple.c
===================================================================
--- gcc/gimple.c	(revision 182366)
+++ gcc/gimple.c	(working copy)
@@ -3318,11 +3318,21 @@ compare_type_names_p (tree t1, tree t2)
   tree name1 = TYPE_NAME (t1);
   tree name2 = TYPE_NAME (t2);
 
-  if (name1 && TREE_CODE (name1) == TYPE_DECL)
+  if ((name1 != NULL_TREE) != (name2 != NULL_TREE))
+    return false;
+
+  if (name1 == NULL_TREE)
+    return true;
+
+  /* Either both should be a TYPE_DECL or both an IDENTIFIER_NODE.  */
+  if (TREE_CODE (name1) != TREE_CODE (name2))
+    return false;
+
+  if (TREE_CODE (name1) == TYPE_DECL)
     name1 = DECL_NAME (name1);
   gcc_checking_assert (!name1 || TREE_CODE (name1) == IDENTIFIER_NODE);
 
-  if (name2 && TREE_CODE (name2) == TYPE_DECL)
+  if (TREE_CODE (name2) == TYPE_DECL)
     name2 = DECL_NAME (name2);
   gcc_checking_assert (!name2 || TREE_CODE (name2) == IDENTIFIER_NODE);
 
@@ -3537,6 +3547,19 @@ gimple_types_compatible_p_1 (tree t1, tr
   if (!compare_type_names_p (t1, t2))
     goto different_types;
 
+  /* We may not merge typedef types to the same type in different
+     contexts.  */
+  if (TYPE_NAME (t1)
+      && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL
+      && DECL_CONTEXT (TYPE_NAME (t1))
+      && TYPE_P (DECL_CONTEXT (TYPE_NAME (t1))))
+    {
+      if (!gtc_visit (DECL_CONTEXT (TYPE_NAME (t1)),
+		      DECL_CONTEXT (TYPE_NAME (t2)),
+		      state, sccstack, sccstate, sccstate_obstack))
+	goto different_types;
+    }
+
   /* If their attributes are not the same they can't be the same type.  */
   if (!attribute_list_equal (TYPE_ATTRIBUTES (t1), TYPE_ATTRIBUTES (t2)))
     goto different_types;
@@ -3980,6 +4003,7 @@ iterative_hash_name (tree name, hashval_
 {
   if (!name)
     return v;
+  v = iterative_hash_hashval_t (TREE_CODE (name), v);
   if (TREE_CODE (name) == TYPE_DECL)
     name = DECL_NAME (name);
   if (!name)
@@ -4046,6 +4070,12 @@ iterative_hash_gimple_type (tree type, h
      only existing types having the same features as the new type will be
      checked.  */
   v = iterative_hash_name (TYPE_NAME (type), 0);
+  if (TYPE_NAME (type)
+      && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
+      && DECL_CONTEXT (TYPE_NAME (type))
+      && TYPE_P (DECL_CONTEXT (TYPE_NAME (type))))
+    v = visit (DECL_CONTEXT (TYPE_NAME (type)), state, v,
+	       sccstack, sccstate, sccstate_obstack);
   v = iterative_hash_hashval_t (TREE_CODE (type), v);
   v = iterative_hash_hashval_t (TYPE_QUALS (type), v);
   v = iterative_hash_hashval_t (TREE_ADDRESSABLE (type), v);
Index: gcc/testsuite/g++.dg/lto/pr51567-1_0.C
===================================================================
--- gcc/testsuite/g++.dg/lto/pr51567-1_0.C	(revision 0)
+++ gcc/testsuite/g++.dg/lto/pr51567-1_0.C	(revision 0)
@@ -0,0 +1,27 @@
+// { dg-lto-do link }
+// { dg-lto-options { { -flto -g } } }
+
+struct _Deque_iterator {
+    int* _M_cur;
+    void foo() {}
+};
+class _Deque_base {
+public:
+    typedef _Deque_iterator iterator;
+    iterator _M_impl;
+};
+class deque : public _Deque_base {
+public:
+    typedef _Deque_base::iterator iterator;
+};
+class OutputContextStack {
+public:
+    deque m_stack;
+    deque::iterator m_stackPosition;
+};
+int main()
+{
+  OutputContextStack s;
+  s.m_stackPosition.foo();
+}
+


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