diff options
author | Dodji Seketeli <dodji@redhat.com> | 2009-12-11 14:36:05 +0000 |
---|---|---|
committer | Dodji Seketeli <dodji@gcc.gnu.org> | 2009-12-11 15:36:05 +0100 |
commit | 9cf10655bb78b500581f2e3e9bfd0d44cbee7d5c (patch) | |
tree | fcebb61777e39028dfd13660e12098519b9ca084 /gcc | |
parent | c9e900454a397fc14d0ba4bdef23fd3154314fbe (diff) | |
download | gcc-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/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 2 | ||||
-rw-r--r-- | gcc/cp/tree.c | 16 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/typedef24.C | 33 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/typedef25.C | 43 |
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> >(); +} + |