This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR51567
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jan Hubicka <jh at suse dot de>
- Date: Thu, 15 Dec 2011 17:34:37 +0100 (CET)
- Subject: [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();
+}
+