Commit 7088fca9 by Kriang Lerdsuwanakij Committed by Kriang Lerdsuwanakij

Core issue 287, PR c++/7639

	Core issue 287, PR c++/7639
	* cp-tree.h (lang_type_class): Add decl_list field.
	(CLASSTYPE_DECL_LIST): New macro.
	(maybe_add_class_template_decl_list): Add declaration.
	* class.c (duplicate_tag_error): Initialize CLASSTYPE_DECL_LIST.
	(unreverse_member_declarations): Reverse CLASSTYPE_DECL_LIST.
	(maybe_add_class_template_decl_list): New function.
	(add_implicitly_declared_members): Use it.
	* decl.c (maybe_process_template_type_declaration): Likewise.
	(pushtag): Likewise.
	* friend.c (add_friend): Likewise.
	(make_friend_class): Likewise.
	* semantics.c (finish_member_declaration): Likewise.
	(begin_class_definition): Initialize CLASSTYPE_DECL_LIST.
	* pt.c (instantiate_class_template): Use CLASSTYPE_DECL_LIST
	to process members and friends in the order of declaration.

	Core issue 287, PR c++/7639
	* g++.dg/template/instantiate1.C: Adjust error location.
	* g++.dg/template/instantiate3.C: New test.
	* g++.old-deja/g++.pt/crash10.C: Adjust error location.
	* g++.old-deja/g++.pt/derived3.C: Adjust error location.
	* g++.old-deja/g++.pt/spec28.C: Reorder declaration.

From-SVN: r58654
parent d2d199a3
2002-10-30 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Core issue 287, PR c++/7639
* cp-tree.h (lang_type_class): Add decl_list field.
(CLASSTYPE_DECL_LIST): New macro.
(maybe_add_class_template_decl_list): Add declaration.
* class.c (duplicate_tag_error): Initialize CLASSTYPE_DECL_LIST.
(unreverse_member_declarations): Reverse CLASSTYPE_DECL_LIST.
(maybe_add_class_template_decl_list): New function.
(add_implicitly_declared_members): Use it.
* decl.c (maybe_process_template_type_declaration): Likewise.
(pushtag): Likewise.
* friend.c (add_friend): Likewise.
(make_friend_class): Likewise.
* semantics.c (finish_member_declaration): Likewise.
(begin_class_definition): Initialize CLASSTYPE_DECL_LIST.
* pt.c (instantiate_class_template): Use CLASSTYPE_DECL_LIST
to process members and friends in the order of declaration.
2002-10-29 Mark Mitchell <mark@codesourcery.com> 2002-10-29 Mark Mitchell <mark@codesourcery.com>
PR c++/8287 PR c++/8287
......
...@@ -2093,6 +2093,7 @@ duplicate_tag_error (t) ...@@ -2093,6 +2093,7 @@ duplicate_tag_error (t)
TYPE_REDEFINED (t) = 1; TYPE_REDEFINED (t) = 1;
CLASSTYPE_TEMPLATE_INFO (t) = template_info; CLASSTYPE_TEMPLATE_INFO (t) = template_info;
CLASSTYPE_USE_TEMPLATE (t) = use_template; CLASSTYPE_USE_TEMPLATE (t) = use_template;
CLASSTYPE_DECL_LIST (t) = NULL_TREE;
} }
TYPE_SIZE (t) = NULL_TREE; TYPE_SIZE (t) = NULL_TREE;
TYPE_MODE (t) = VOIDmode; TYPE_MODE (t) = VOIDmode;
...@@ -2744,6 +2745,29 @@ finish_struct_anon (t) ...@@ -2744,6 +2745,29 @@ finish_struct_anon (t)
} }
} }
/* Add T to CLASSTYPE_DECL_LIST of current_class_type which
will be used later during class template instantiation.
When FRIEND_P is zero, T can be a static member data (VAR_DECL),
a non-static member data (FIELD_DECL), a member function
(FUNCTION_DECL), a nested type (RECORD_TYPE, ENUM_TYPE),
a typedef (TYPE_DECL) or a member class template (TEMPLATE_DECL)
When FRIEND_P is nonzero, T is either a friend class
(RECORD_TYPE, TEMPLATE_DECL) or a friend function
(FUNCTION_DECL, TEMPLATE_DECL). */
void
maybe_add_class_template_decl_list (type, t, friend_p)
tree type;
tree t;
int friend_p;
{
/* Save some memory by not creating TREE_LIST if TYPE is not template. */
if (CLASSTYPE_TEMPLATE_INFO (type))
CLASSTYPE_DECL_LIST (type)
= tree_cons (friend_p ? NULL_TREE : type,
t, CLASSTYPE_DECL_LIST (type));
}
/* Create default constructors, assignment operators, and so forth for /* Create default constructors, assignment operators, and so forth for
the type indicated by T, if they are needed. the type indicated by T, if they are needed.
CANT_HAVE_DEFAULT_CTOR, CANT_HAVE_CONST_CTOR, and CANT_HAVE_DEFAULT_CTOR, CANT_HAVE_CONST_CTOR, and
...@@ -2824,7 +2848,10 @@ add_implicitly_declared_members (t, cant_have_default_ctor, ...@@ -2824,7 +2848,10 @@ add_implicitly_declared_members (t, cant_have_default_ctor,
/* Now, hook all of the new functions on to TYPE_METHODS, /* Now, hook all of the new functions on to TYPE_METHODS,
and add them to the CLASSTYPE_METHOD_VEC. */ and add them to the CLASSTYPE_METHOD_VEC. */
for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f)) for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f))
add_method (t, *f, /*error_p=*/0); {
add_method (t, *f, /*error_p=*/0);
maybe_add_class_template_decl_list (current_class_type, *f, /*friend_p=*/0);
}
*f = TYPE_METHODS (t); *f = TYPE_METHODS (t);
TYPE_METHODS (t) = implicit_fns; TYPE_METHODS (t) = implicit_fns;
...@@ -5305,10 +5332,11 @@ unreverse_member_declarations (t) ...@@ -5305,10 +5332,11 @@ unreverse_member_declarations (t)
tree prev; tree prev;
tree x; tree x;
/* The TYPE_FIELDS, TYPE_METHODS, and CLASSTYPE_TAGS are all in /* The following lists are all in reverse order. Put them in
reverse order. Put them in declaration order now. */ declaration order now. */
TYPE_METHODS (t) = nreverse (TYPE_METHODS (t)); TYPE_METHODS (t) = nreverse (TYPE_METHODS (t));
CLASSTYPE_TAGS (t) = nreverse (CLASSTYPE_TAGS (t)); CLASSTYPE_TAGS (t) = nreverse (CLASSTYPE_TAGS (t));
CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t));
/* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in /* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in
reverse order, so we can't just use nreverse. */ reverse order, so we can't just use nreverse. */
......
...@@ -1159,6 +1159,7 @@ struct lang_type_class GTY(()) ...@@ -1159,6 +1159,7 @@ struct lang_type_class GTY(())
tree friend_classes; tree friend_classes;
tree rtti; tree rtti;
tree methods; tree methods;
tree decl_list;
tree template_info; tree template_info;
tree befriending_classes; tree befriending_classes;
}; };
...@@ -1295,6 +1296,12 @@ struct lang_type GTY(()) ...@@ -1295,6 +1296,12 @@ struct lang_type GTY(())
functions are sorted, once the class is complete. */ functions are sorted, once the class is complete. */
#define CLASSTYPE_METHOD_VEC(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->methods) #define CLASSTYPE_METHOD_VEC(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->methods)
/* For class templates, this is a TREE_LIST of all member data,
functions, types, and friends in the order of declaration.
The TREE_PURPOSE of each TREE_LIST is NULL_TREE for a friend,
and the RECORD_TYPE for the class template otherwise. */
#define CLASSTYPE_DECL_LIST(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->decl_list)
/* The slot in the CLASSTYPE_METHOD_VEC where constructors go. */ /* The slot in the CLASSTYPE_METHOD_VEC where constructors go. */
#define CLASSTYPE_CONSTRUCTOR_SLOT 0 #define CLASSTYPE_CONSTRUCTOR_SLOT 0
...@@ -3572,6 +3579,7 @@ extern void cxx_print_error_function PARAMS ((struct diagnostic_context *, ...@@ -3572,6 +3579,7 @@ extern void cxx_print_error_function PARAMS ((struct diagnostic_context *,
extern void build_self_reference PARAMS ((void)); extern void build_self_reference PARAMS ((void));
extern int same_signature_p PARAMS ((tree, tree)); extern int same_signature_p PARAMS ((tree, tree));
extern void warn_hidden PARAMS ((tree)); extern void warn_hidden PARAMS ((tree));
extern void maybe_add_class_template_decl_list PARAMS ((tree, tree, int));
extern tree get_enclosing_class PARAMS ((tree)); extern tree get_enclosing_class PARAMS ((tree));
int is_base_of_enclosing_class PARAMS ((tree, tree)); int is_base_of_enclosing_class PARAMS ((tree, tree));
extern void unreverse_member_declarations PARAMS ((tree)); extern void unreverse_member_declarations PARAMS ((tree));
......
...@@ -2617,7 +2617,11 @@ maybe_process_template_type_declaration (type, globalize, b) ...@@ -2617,7 +2617,11 @@ maybe_process_template_type_declaration (type, globalize, b)
b->level_chain->tags = b->level_chain->tags =
tree_cons (name, type, b->level_chain->tags); tree_cons (name, type, b->level_chain->tags);
if (!COMPLETE_TYPE_P (current_class_type)) if (!COMPLETE_TYPE_P (current_class_type))
CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags; {
maybe_add_class_template_decl_list (current_class_type,
type, /*friend_p=*/0);
CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags;
}
} }
} }
} }
...@@ -2781,7 +2785,11 @@ pushtag (name, type, globalize) ...@@ -2781,7 +2785,11 @@ pushtag (name, type, globalize)
if (b->parm_flag == 2) if (b->parm_flag == 2)
{ {
if (!COMPLETE_TYPE_P (current_class_type)) if (!COMPLETE_TYPE_P (current_class_type))
CLASSTYPE_TAGS (current_class_type) = b->tags; {
maybe_add_class_template_decl_list (current_class_type,
type, /*friend_p=*/0);
CLASSTYPE_TAGS (current_class_type) = b->tags;
}
} }
} }
......
...@@ -159,6 +159,9 @@ add_friend (type, decl) ...@@ -159,6 +159,9 @@ add_friend (type, decl)
return; return;
} }
} }
maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
TREE_VALUE (list) = tree_cons (error_mark_node, decl, TREE_VALUE (list) = tree_cons (error_mark_node, decl,
TREE_VALUE (list)); TREE_VALUE (list));
return; return;
...@@ -166,6 +169,8 @@ add_friend (type, decl) ...@@ -166,6 +169,8 @@ add_friend (type, decl)
list = TREE_CHAIN (list); list = TREE_CHAIN (list);
} }
maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
DECL_FRIENDLIST (typedecl) DECL_FRIENDLIST (typedecl)
= tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl), = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
DECL_FRIENDLIST (typedecl)); DECL_FRIENDLIST (typedecl));
...@@ -267,6 +272,8 @@ make_friend_class (type, friend_type) ...@@ -267,6 +272,8 @@ make_friend_class (type, friend_type)
TREE_VALUE (classes), type); TREE_VALUE (classes), type);
else else
{ {
maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1);
CLASSTYPE_FRIEND_CLASSES (type) CLASSTYPE_FRIEND_CLASSES (type)
= tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type)); = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
if (is_template_friend) if (is_template_friend)
......
...@@ -1754,6 +1754,7 @@ begin_class_definition (t) ...@@ -1754,6 +1754,7 @@ begin_class_definition (t)
TYPE_BINFO_BASETYPES (t) = NULL_TREE; TYPE_BINFO_BASETYPES (t) = NULL_TREE;
TYPE_FIELDS (t) = NULL_TREE; TYPE_FIELDS (t) = NULL_TREE;
TYPE_METHODS (t) = NULL_TREE; TYPE_METHODS (t) = NULL_TREE;
CLASSTYPE_DECL_LIST (t) = NULL_TREE;
CLASSTYPE_TAGS (t) = NULL_TREE; CLASSTYPE_TAGS (t) = NULL_TREE;
CLASSTYPE_VBASECLASSES (t) = NULL_TREE; CLASSTYPE_VBASECLASSES (t) = NULL_TREE;
TYPE_SIZE (t) = NULL_TREE; TYPE_SIZE (t) = NULL_TREE;
...@@ -1835,6 +1836,8 @@ finish_member_declaration (decl) ...@@ -1835,6 +1836,8 @@ finish_member_declaration (decl)
if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c) if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c)
SET_DECL_LANGUAGE (decl, lang_cplusplus); SET_DECL_LANGUAGE (decl, lang_cplusplus);
maybe_add_class_template_decl_list (current_class_type, decl, /*friend_p=*/0);
/* Put functions on the TYPE_METHODS list and everything else on the /* Put functions on the TYPE_METHODS list and everything else on the
TYPE_FIELDS list. Note that these are built up in reverse order. TYPE_FIELDS list. Note that these are built up in reverse order.
We reverse them (to obtain declaration order) in finish_struct. */ We reverse them (to obtain declaration order) in finish_struct. */
......
2002-10-30 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Core issue 287, PR c++/7639
* g++.dg/template/instantiate1.C: Adjust error location.
* g++.dg/template/instantiate3.C: New test.
* g++.old-deja/g++.pt/crash10.C: Adjust error location.
* g++.old-deja/g++.pt/derived3.C: Adjust error location.
* g++.old-deja/g++.pt/spec28.C: Reorder declaration.
2002-10-29 Hans-Peter Nilsson <hp@bitrange.com> 2002-10-29 Hans-Peter Nilsson <hp@bitrange.com>
* lib/compat.exp (compat-execute): Don't clean out a gluefile. * lib/compat.exp (compat-execute): Don't clean out a gluefile.
......
...@@ -8,12 +8,12 @@ template <class T> struct X { ...@@ -8,12 +8,12 @@ template <class T> struct X {
T t; // { dg-error "incomplete" } T t; // { dg-error "incomplete" }
}; };
template <class T> struct Y { // { dg-error "instantiated" } template <class T> struct Y {
X<T> x; X<T> x; // { dg-error "instantiated" }
}; };
template <class T> struct Z { // { dg-error "instantiated|declaration" } template <class T> struct Z { // { dg-error "declaration" }
Y<Z<T> > y; Y<Z<T> > y; // { dg-error "instantiated" }
}; };
struct ZZ : Z<int> struct ZZ : Z<int>
......
// { dg-do compile }
// Origin: Scott Snyder <snyder@fnal.gov>
// PR c++/7639
// ICE when accessing member with incomplete type.
class ACE_Null_Mutex; // { dg-error "forward declaration" }
template <class TYPE>
struct ACE_Cleanup_Adapter
{
TYPE &object ()
{ return object_; } // { dg-error "no member" }
TYPE object_; // { dg-error "incomplete type" }
};
template class ACE_Cleanup_Adapter<ACE_Null_Mutex>; // { dg-error "instantiated from here" }
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
template<int M, int N> template<int M, int N>
class GCD { class GCD {
public: public:
enum { val = (N == 0) ? M : GCD<N, M % N>::val }; enum { val = (N == 0) ? M : GCD<N, M % N>::val }; // ERROR - division
}; };
int main() { int main() {
GCD< 1, 0 >::val; // ERROR - division GCD< 1, 0 >::val; // ERROR - instantiated
} }
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
template<class T> template<class T>
class X { class X {
class Y : public T {}; // ERROR - invalid base type class Y : public T {};
Y y; Y y; // ERROR - invalid base type
}; };
int main() { int main() {
X<int> x; X<int> x; // ERROR - instantiated
} }
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
template <class T> template <class T>
struct S1 { struct S1 {
friend bool f<>(const S1&);
typedef T X; typedef T X;
friend bool f<>(const S1&);
}; };
template <class T> template <class T>
......
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