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
This commit is contained in:
parent
c9e900454a
commit
9cf10655bb
|
@ -1,3 +1,15 @@
|
|||
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
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
|
||||
|
|
|
@ -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> >();
|
||||
}
|
||||
|
|
@ -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> >();
|
||||
}
|
||||
|
Loading…
Reference in New Issue