aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2009-12-11 14:36:05 +0000
committerDodji Seketeli <dodji@gcc.gnu.org>2009-12-11 15:36:05 +0100
commit9cf10655bb78b500581f2e3e9bfd0d44cbee7d5c (patch)
treefcebb61777e39028dfd13660e12098519b9ca084 /gcc
parentc9e900454a397fc14d0ba4bdef23fd3154314fbe (diff)
downloadgcc-9cf10655bb78b500581f2e3e9bfd0d44cbee7d5c.zip
gcc-9cf10655bb78b500581f2e3e9bfd0d44cbee7d5c.tar.gz
gcc-9cf10655bb78b500581f2e3e9bfd0d44cbee7d5c.tar.bz2
re PR c++/42225 (GCC 4.5 ICE (segfault) on C++ templated code)
Fix PR c++/42225 gcc/cp/ChangeLog: PR c++/42225 * typeck.c (incompatible_dependent_typedefs_p): New function. (structural_comptypes): Use it. * cp-tree.h (cp_set_underlying_type): Declare ... * tree.c (cp_set_underlying_type): ... new function. * class.c (build_self_reference): Use cp_set_underlying_type instead of set_underlying_type. * decl2.c (grokfield): Likewise. * name-lookup.c (pushdecl_maybe_friend): Likewise. gcc/testsuite/ChangeLog: PR c++/42225 * g++.dg/template/typedef24.C: New test. * g++.dg/template/typedef25.C: New test. From-SVN: r155160
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/name-lookup.c2
-rw-r--r--gcc/cp/tree.c16
-rw-r--r--gcc/cp/typeck.c44
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/template/typedef24.C33
-rw-r--r--gcc/testsuite/g++.dg/template/typedef25.C43
10 files changed, 158 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 19e751d..988f98f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,17 @@
2009-12-11 Dodji Seketeli <dodji@redhat.com>
+ PR c++/42225
+ * typeck.c (incompatible_dependent_typedefs_p): New function.
+ (structural_comptypes): Use it.
+ * cp-tree.h (cp_set_underlying_type): Declare ...
+ * tree.c (cp_set_underlying_type): ... new function.
+ * class.c (build_self_reference): Use cp_set_underlying_type
+ instead of set_underlying_type.
+ * decl2.c (grokfield): Likewise.
+ * name-lookup.c (pushdecl_maybe_friend): Likewise.
+
+2009-12-11 Dodji Seketeli <dodji@redhat.com>
+
PR c++/42251
* pt.c (convert_template_argument): Avoid missing folding of SCOPE_REFs.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index ca75bc1..fff4380 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6514,7 +6514,7 @@ build_self_reference (void)
DECL_CONTEXT (value) = current_class_type;
DECL_ARTIFICIAL (value) = 1;
SET_DECL_SELF_REFERENCE_P (value);
- set_underlying_type (value);
+ cp_set_underlying_type (value);
if (processing_template_decl)
value = push_template_decl (value);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 21a914d..d0a0435 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5189,6 +5189,7 @@ extern bool class_tmpl_impl_spec_p (const_tree);
extern int zero_init_p (const_tree);
extern tree strip_typedefs (tree);
extern bool typedef_variant_p (tree);
+extern void cp_set_underlying_type (tree);
extern tree copy_binfo (tree, tree, tree,
tree *, int);
extern int member_p (const_tree);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index d4a866a..2b284fb 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -844,7 +844,7 @@ grokfield (const cp_declarator *declarator,
if (declspecs->specs[(int)ds_typedef]
&& TREE_TYPE (value) != error_mark_node
&& TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (value))) != value)
- set_underlying_type (value);
+ cp_set_underlying_type (value);
return value;
}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 6b8dcc7..1371c8a 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -874,7 +874,7 @@ pushdecl_maybe_friend (tree x, bool is_friend)
inlining. */
&& (!TYPE_NAME (type)
|| TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x))))
- set_underlying_type (x);
+ cp_set_underlying_type (x);
if (type != error_mark_node
&& TYPE_NAME (type)
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 17fc495..7097f8c 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1076,6 +1076,22 @@ typedef_variant_p (tree type)
return is_typedef_decl (TYPE_NAME (type));
}
+/* Setup a TYPE_DECL node as a typedef representation.
+ See comments of set_underlying_type in c-common.c. */
+
+void
+cp_set_underlying_type (tree t)
+{
+ set_underlying_type (t);
+ /* If the typedef variant type is dependent, make it require
+ structural equality.
+ This is useful when comparing two dependent typedef variant types,
+ because it forces the comparison of the template parameters of their
+ decls for instance. */
+ if (dependent_type_p (TREE_TYPE (t)))
+ SET_TYPE_STRUCTURAL_EQUALITY (TREE_TYPE (t));
+}
+
/* Makes a copy of BINFO and TYPE, which is to be inherited into a
graph dominated by T. If BINFO is NULL, TYPE is a dependent base,
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 36c0b8a..791b506 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1073,6 +1073,47 @@ comp_array_types (const_tree t1, const_tree t2, bool allow_redeclaration)
return true;
}
+/* Subroutine of structural_comptypes.
+ Compare the template parameters of the
+ typedef decl of T1 and T2.
+ Return TRUE if the template parameters of the typedef decls of T1 and T2 are
+ different, FALSE otherwise. */
+
+static bool
+incompatible_dependent_typedefs_p (tree t1, tree t2)
+{
+ tree decl1, tinfo1,
+ decl2, tinfo2;
+
+ if (!typedef_variant_p (t1)
+ || !typedef_variant_p (t2)
+ || !dependent_type_p (t1)
+ || !dependent_type_p (t2))
+ return false;
+
+ decl1 = TYPE_NAME (t1);
+ decl2 = TYPE_NAME (t2);
+ if (decl1 == decl2)
+ return false ;
+
+ tinfo1 = get_template_info (decl1);
+ if (!tinfo1)
+ tinfo1 = get_template_info (DECL_CONTEXT (decl1));
+
+ tinfo2 = get_template_info (decl2);
+ if (!tinfo2)
+ tinfo2 = get_template_info (DECL_CONTEXT (decl2));
+
+ gcc_assert (tinfo1 != NULL_TREE
+ && tinfo2 != NULL_TREE);
+
+ if (tinfo1 == tinfo2)
+ return false;
+
+ return !comp_template_parms (DECL_TEMPLATE_PARMS (TI_TEMPLATE (tinfo1)),
+ DECL_TEMPLATE_PARMS (TI_TEMPLATE (tinfo2)));
+}
+
/* Subroutine in comptypes. */
static bool
@@ -1120,6 +1161,9 @@ structural_comptypes (tree t1, tree t2, int strict)
&& TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
return true;
+ if (incompatible_dependent_typedefs_p (t1, t2))
+ return false;
+
/* Compare the types. Break out if they could be the same. */
switch (TREE_CODE (t1))
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 98744464..18343a2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2009-12-11 Dodji Seketeli <dodji@redhat.com>
+ PR c++/42225
+ * g++.dg/template/typedef24.C: New test.
+ * g++.dg/template/typedef25.C: New test.
+
+2009-12-11 Dodji Seketeli <dodji@redhat.com>
+
PR c++/42251
* g++.dg/template/const3.C: New test.
diff --git a/gcc/testsuite/g++.dg/template/typedef24.C b/gcc/testsuite/g++.dg/template/typedef24.C
new file mode 100644
index 0000000..ddcae1d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typedef24.C
@@ -0,0 +1,33 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/42225
+// { dg-do compile }
+
+template<class T>
+struct A
+{
+ typedef T I;
+};
+
+template<class T, int>
+struct B
+{
+ typedef T TT;
+ typedef typename TT::I TT_I;
+ typedef A<TT_I> TA;
+};
+
+template<class T>
+void
+foo()
+{
+ typedef T TT;
+ typedef typename TT::I TT_I;
+ typedef A<TT_I> TA;
+}
+
+int
+main()
+{
+ foo<A<int> >();
+}
+
diff --git a/gcc/testsuite/g++.dg/template/typedef25.C b/gcc/testsuite/g++.dg/template/typedef25.C
new file mode 100644
index 0000000..4f5868f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typedef25.C
@@ -0,0 +1,43 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/42225
+// { dg-options "-std=c++0x" }
+// { dg-do compile }
+
+template<class T>
+struct A
+{
+ typedef T I;
+ static const char *i;
+};
+
+template<class T, int>
+struct B
+{
+ typedef T TT;
+ typedef decltype(TT::i) TT_I0;
+ typedef decltype(&TT::i) TT_I1;
+ typedef decltype(*TT::i) TT_I2;
+ typedef A<TT_I0> TA0;
+ typedef A<TT_I1> TA1;
+ typedef A<TT_I2> TA2;
+};
+
+template<class T>
+void
+foo()
+{
+ typedef T TT;
+ typedef decltype(TT::i) TT_I0;
+ typedef decltype(&TT::i) TT_I1;
+ typedef decltype(*TT::i) TT_I2;
+ typedef A<TT_I0> TA0;
+ typedef A<TT_I1> TA1;
+ typedef A<TT_I2> TA2;
+}
+
+int
+main()
+{
+ foo<A<int> >();
+}
+