Commit 9cf10655 by Dodji Seketeli Committed by Dodji Seketeli

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
parent c9e90045
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.
......
......@@ -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))
{
......
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.
......
// 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> >();
}
// 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> >();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment