diff options
author | Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> | 2003-08-01 15:06:02 +0000 |
---|---|---|
committer | Kriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org> | 2003-08-01 15:06:02 +0000 |
commit | cbd63935d8cb0edec8d27a7c427106b41d85a29f (patch) | |
tree | cfa3a63f72156106d2f13838ea20b64ffacdbb1f | |
parent | ee3071efe506d022e4cad7d81354724c01e0f932 (diff) | |
download | gcc-cbd63935d8cb0edec8d27a7c427106b41d85a29f.zip gcc-cbd63935d8cb0edec8d27a7c427106b41d85a29f.tar.gz gcc-cbd63935d8cb0edec8d27a7c427106b41d85a29f.tar.bz2 |
PR c++/8442, c++/8806
PR c++/8442, c++/8806
* decl.c (qualify_lookup): Accept TEMPLATE_DECL if types are
preferred.
(check_elaborated_type_specifier): Add allow_template_p
parameter. Check tag mismatch and class template.
(xref_tag): Add template_header_p parameter. Add assertion
that name is an IDENTIFIER_NODE. Remove implicit typename
warning. Simplify lookup process if globalize is true.
(cxx_init_decl_processing): Adjust call to xref_tag.
(xref_tag_from_type): Likewise.
* decl2.c (handle_class_head): Likewise.
* parser.c (cp_parser_elaborated_type_specifier,
cp_parser_class_head): Likewise.
* rtti.c (init_rtti_processing, build_dynamic_cast1,
tinfo_base_init, emit_support_tinfos): Likewise.
* class.c (is_base_of_enclosing_class): Remove.
* pt.c (convert_template_argument): Don't accept RECORD_TYPE as
template template argument.
* cp-tree.h (xref_tag): Adjust declaration.
(is_base_of_enclosing_class): Remove.
* NEWS: Document template template argument change.
* g++.dg/template/elab1.C: Likewise.
* g++.dg/template/type2.C: Likewise.
* g++.dg/template/ttp3.C: Adjust expected error message.
* g++.old-deja/g++.law/visibility13.C: Likewise.
* g++.old-deja/g++.niklas/t135.C: Likewise.
* g++.old-deja/g++.pt/ttp41.C: Likewise.
* g++.old-deja/g++.pt/ttp43.C: Use qualified name for template
template argument.
* g++.old-deja/g++.pt/ttp44.C: Likewise.
From-SVN: r70048
-rw-r--r-- | gcc/cp/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/cp/NEWS | 13 | ||||
-rw-r--r-- | gcc/cp/class.c | 15 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/decl.c | 212 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 26 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/elab1.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/ttp3.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/type2.C | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.law/visibility13.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.niklas/t135.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/ttp41.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/ttp43.C | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/ttp44.C | 4 |
18 files changed, 210 insertions, 171 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 83b901e..c50f99f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,27 @@ +2003-08-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/8442, c++/8806 + * decl.c (qualify_lookup): Accept TEMPLATE_DECL if types are + preferred. + (check_elaborated_type_specifier): Add allow_template_p + parameter. Check tag mismatch and class template. + (xref_tag): Add template_header_p parameter. Add assertion + that name is an IDENTIFIER_NODE. Remove implicit typename + warning. Simplify lookup process if globalize is true. + (cxx_init_decl_processing): Adjust call to xref_tag. + (xref_tag_from_type): Likewise. + * decl2.c (handle_class_head): Likewise. + * parser.c (cp_parser_elaborated_type_specifier, + cp_parser_class_head): Likewise. + * rtti.c (init_rtti_processing, build_dynamic_cast1, + tinfo_base_init, emit_support_tinfos): Likewise. + * class.c (is_base_of_enclosing_class): Remove. + * pt.c (convert_template_argument): Don't accept RECORD_TYPE as + template template argument. + * cp-tree.h (xref_tag): Adjust declaration. + (is_base_of_enclosing_class): Remove. + * NEWS: Document template template argument change. + 2003-08-01 Nathan Sidwell <nathan@codesourcery.com> * parser.c (cp_parser_init_declarator, diff --git a/gcc/cp/NEWS b/gcc/cp/NEWS index 2642aed..00a50e4 100644 --- a/gcc/cp/NEWS +++ b/gcc/cp/NEWS @@ -76,6 +76,19 @@ removed. * Covariant returns are implemented for all but varadic functions that require an adjustment. +* Inside the scope of a template class, the name of the class itself + is no longer a valid template template argument. Instead, you now have + to qualify the name by its scope. For example: + + template <template <class> class TT> class X {}; + template <class T> class Y { + X<Y> x; // Invalid. + }; + + The valid code for the above example is: + + X< ::Y> x; // Valid. Note that `<:' is a digraph and means `['. + *** Changes in GCC 3.3: * The "new X = 3" extension has been removed; you must now use "new X(3)". diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 527eae4..4ff41fb 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -6333,21 +6333,6 @@ get_enclosing_class (tree type) return NULL_TREE; } -/* Return 1 if TYPE or one of its enclosing classes is derived from BASE. */ - -int -is_base_of_enclosing_class (tree base, tree type) -{ - while (type) - { - if (lookup_base (type, base, ba_any, NULL)) - return 1; - - type = get_enclosing_class (type); - } - return 0; -} - /* Note that NAME was looked up while the current class was being defined and that the result of that lookup was DECL. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f62255b..cfb765a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3603,7 +3603,6 @@ extern int same_signature_p (tree, tree); extern void warn_hidden (tree); extern void maybe_add_class_template_decl_list (tree, tree, int); extern tree get_enclosing_class (tree); -int is_base_of_enclosing_class (tree, tree); extern void unreverse_member_declarations (tree); extern void invalidate_class_lookup_cache (void); extern void maybe_note_name_used_in_class (tree, tree); @@ -3731,7 +3730,7 @@ extern tree get_scope_of_declarator (tree); extern void grok_special_member_properties (tree); extern int grok_ctor_properties (tree, tree); extern void grok_op_properties (tree, int); -extern tree xref_tag (enum tag_types, tree, tree, bool); +extern tree xref_tag (enum tag_types, tree, tree, bool, bool); extern tree xref_tag_from_type (tree, tree, int); extern void xref_basetypes (tree, tree); extern tree start_enum (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3ed6744..95984c9 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5753,7 +5753,8 @@ qualify_lookup (tree val, int flags) return val; if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL) return val; - if ((flags & LOOKUP_PREFER_TYPES) && TREE_CODE (val) == TYPE_DECL) + if ((flags & LOOKUP_PREFER_TYPES) + && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL)) return val; if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES)) return NULL_TREE; @@ -6339,7 +6340,7 @@ cxx_init_decl_processing (void) push_namespace (std_identifier); bad_alloc_type_node = xref_tag (class_type, get_identifier ("bad_alloc"), - /*attributes=*/NULL_TREE, 1); + /*attributes=*/NULL_TREE, true, false); pop_namespace (); ptr_ftype_sizetype = build_function_type (ptr_type_node, @@ -12553,15 +12554,15 @@ tag_name (enum tag_types code) /* Name lookup in an elaborated-type-specifier (after the keyword indicated by TAG_CODE) has found TYPE. If the elaborated-type-specifier is invalid, issue a diagnostic and return - error_mark_node; otherwise, return TYPE itself. */ + error_mark_node; otherwise, return TYPE itself. + If ALLOW_TEMPLATE_P is true, TYPE may be a class template. */ static tree check_elaborated_type_specifier (enum tag_types tag_code, - tree type) + tree type, + bool allow_template_p) { - tree t; - - t = follow_tag_typedef (type); + tree t = follow_tag_typedef (type); /* [dcl.type.elab] If the identifier resolves to a typedef-name or a template type-parameter, the elaborated-type-specifier is @@ -12578,30 +12579,67 @@ check_elaborated_type_specifier (enum tag_types tag_code, type, tag_name (tag_code)); t = error_mark_node; } + else if (TREE_CODE (type) != RECORD_TYPE + && TREE_CODE (type) != UNION_TYPE + && tag_code != enum_type) + { + error ("`%T' referred to as `%s'", type, tag_name (tag_code)); + t = error_mark_node; + } + else if (TREE_CODE (type) != ENUMERAL_TYPE + && tag_code == enum_type) + { + error ("`%T' referred to as enum", type); + t = error_mark_node; + } + else if (!allow_template_p + && TREE_CODE (type) == RECORD_TYPE + && CLASSTYPE_IS_TEMPLATE (type)) + { + /* If a class template appears as elaborated type specifier + without a template header such as: + + template <class T> class C {}; + void f(class C); // No template header here + + then the required template argument is missing. */ + + error ("template argument required for `%s %T'", + tag_name (tag_code), + DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))); + t = error_mark_node; + } return t; } -/* Get the struct, enum or union (CODE says which) with tag NAME. +/* Get the struct, enum or union (TAG_CODE says which) with tag NAME. Define the tag as a forward-reference if it is not defined. - C++: If a class derivation is given, process it here, and report - an error if multiple derivation declarations are not identical. + If a declaration is given, process it here, and report an error if + multiple declarations are not identical. ATTRIBUTE is the attribute + appeared in this declaration. - If this is a definition, come in through xref_tag and only look in + GLOBALIZE is false when this is also a definition. Only look in the current frame for the name (since C++ allows new names in any - scope.) */ + scope.) + + TEMPLATE_HEADER_P is true when this declaration is preceded by + a set of template parameters. */ tree xref_tag (enum tag_types tag_code, tree name, tree attributes, - bool globalize) + bool globalize, bool template_header_p) { enum tree_code code; - register tree ref, t; + register tree t; struct cp_binding_level *b = current_binding_level; tree context = NULL_TREE; timevar_push (TV_NAME_LOOKUP); + + my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0); + switch (tag_code) { case record_type: @@ -12618,93 +12656,50 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes, abort (); } - /* If a cross reference is requested, look up the type - already defined for this tag and return it. */ - if (TYPE_P (name)) - { - t = name; - name = TYPE_IDENTIFIER (t); - } - else - t = IDENTIFIER_TYPE_VALUE (name); - - /* Warn about 'friend struct Inherited;' doing the wrong thing. */ - if (t && globalize && TREE_CODE (t) == TYPENAME_TYPE) - { - static int explained; - tree shadowed; - - warning ("`%s %T' declares a new type at namespace scope", - tag_name (tag_code), name); - if (!explained++) - warning (" names from dependent base classes are not visible to unqualified name lookup - to refer to the inherited type, say `%s %T::%T'", - tag_name (tag_code), - constructor_name (current_class_type), - TYPE_IDENTIFIER (t)); - - /* We need to remove the class scope binding for the - TYPENAME_TYPE as otherwise poplevel_class gets confused. */ - for (shadowed = b->class_shadowed; - shadowed; - shadowed = TREE_CHAIN (shadowed)) - if (TREE_TYPE (shadowed) == TYPE_NAME (t)) - { - TREE_PURPOSE (shadowed) = NULL_TREE; - break; - } - } - - if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM - && TREE_CODE (t) != BOUND_TEMPLATE_TEMPLATE_PARM) - t = NULL_TREE; - if (! globalize) { /* If we know we are defining this tag, only look it up in this scope and don't try to find it as a type. */ - ref = lookup_tag (code, name, b, 1); + t = lookup_tag (code, name, b, 1); } else { - if (t) - { - ref = check_elaborated_type_specifier (tag_code, t); - if (ref == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); - } - else - ref = lookup_tag (code, name, b, 0); + tree decl = lookup_name (name, 1); + + if (decl && DECL_CLASS_TEMPLATE_P (decl)) + decl = DECL_TEMPLATE_RESULT (decl); - if (! ref) + if (decl && TREE_CODE (decl) == TYPE_DECL) { - /* Try finding it as a type declaration. If that wins, - use it. */ - ref = lookup_name (name, 1); + /* Two cases we need to consider when deciding if a class + template is allowed as an elaborated type specifier: + 1. It is a self reference to its own class. + 2. It comes with a template header. - if (ref != NULL_TREE - && processing_template_decl - && DECL_CLASS_TEMPLATE_P (ref) - && template_class_depth (current_class_type) == 0) - /* Since GLOBALIZE is true, we're declaring a global - template, so we want this type. */ - ref = DECL_TEMPLATE_RESULT (ref); + For example: - if (ref && TREE_CODE (ref) == TYPE_DECL) - { - ref = check_elaborated_type_specifier (tag_code, - TREE_TYPE (ref)); - if (ref == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); - if (ref && TREE_CODE (ref) != code) - ref = NULL_TREE; - } - else - ref = NULL_TREE; + template <class T> class C { + class C *c1; // DECL_SELF_REFERENCE_P is true + class D; + }; + template <class U> class C; // template_header_p is true + template <class T> class C<T>::D { + class C *c2; // DECL_SELF_REFERENCE_P is true + }; */ + + t = check_elaborated_type_specifier (tag_code, + TREE_TYPE (decl), + template_header_p + | DECL_SELF_REFERENCE_P (decl)); + if (t == error_mark_node) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } + else + t = NULL_TREE; - if (ref && current_class_type + if (t && current_class_type && template_class_depth (current_class_type) - && PROCESSING_REAL_TEMPLATE_DECL_P ()) + && template_header_p) { /* Since GLOBALIZE is nonzero, we are not looking at a definition of this tag. Since, in addition, we are currently @@ -12742,12 +12737,12 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes, accomplish this by making sure that the new type we create to represent this declaration has the right TYPE_CONTEXT. */ - context = TYPE_CONTEXT (ref); - ref = NULL_TREE; + context = TYPE_CONTEXT (t); + t = NULL_TREE; } } - if (! ref) + if (! t) { /* If no such tag is yet defined, create a forward-reference node and record it as the "definition". @@ -12757,44 +12752,41 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes, { error ("use of enum `%#D' without previous declaration", name); - ref = make_node (ENUMERAL_TYPE); + t = make_node (ENUMERAL_TYPE); /* Give the type a default layout like unsigned int to avoid crashing if it does not get defined. */ - TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node); - TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node); - TYPE_USER_ALIGN (ref) = 0; - TREE_UNSIGNED (ref) = 1; - TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node); - TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node); - TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node); + TYPE_MODE (t) = TYPE_MODE (unsigned_type_node); + TYPE_ALIGN (t) = TYPE_ALIGN (unsigned_type_node); + TYPE_USER_ALIGN (t) = 0; + TREE_UNSIGNED (t) = 1; + TYPE_PRECISION (t) = TYPE_PRECISION (unsigned_type_node); + TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (unsigned_type_node); + TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (unsigned_type_node); /* Enable us to recognize when a type is created in class context. To do nested classes correctly, this should probably be cleared out when we leave this classes scope. Currently this in only done in `start_enum'. */ - pushtag (name, ref, globalize); + pushtag (name, t, globalize); } else { - struct cp_binding_level *old_b = class_binding_level; - - ref = make_aggr_type (code); - TYPE_CONTEXT (ref) = context; - pushtag (name, ref, globalize); - class_binding_level = old_b; + t = make_aggr_type (code); + TYPE_CONTEXT (t) = context; + pushtag (name, t, globalize); } } else { - if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref)) - redeclare_class_template (ref, current_template_parms); + if (!globalize && processing_template_decl && IS_AGGR_TYPE (t)) + redeclare_class_template (t, current_template_parms); } - TYPE_ATTRIBUTES (ref) = attributes; + TYPE_ATTRIBUTES (t) = attributes; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ref); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } tree @@ -12810,7 +12802,7 @@ xref_tag_from_type (tree old, tree id, int globalize) if (id == NULL_TREE) id = TYPE_IDENTIFIER (old); - return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize); + return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize, false); } /* REF is a type (named NAME), for which we have just seen some diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a8c6263..6f06860 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4278,7 +4278,7 @@ handle_class_head (enum tag_types tag_kind, tree scope, tree id, if (!decl) { - decl = xref_tag (tag_kind, id, attributes, false); + decl = xref_tag (tag_kind, id, attributes, false, false); if (decl == error_mark_node) return error_mark_node; decl = TYPE_MAIN_DECL (decl); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 63c8172..fce69ca 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -8553,7 +8553,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, (is_friend || !is_declaration || cp_lexer_next_token_is_not (parser->lexer, - CPP_SEMICOLON))); + CPP_SEMICOLON)), + parser->num_template_parameter_lists); } } if (tag_type != enum_type) @@ -11380,7 +11381,8 @@ cp_parser_class_head (cp_parser* parser, /* If the class was unnamed, create a dummy name. */ if (!id) id = make_anon_name (); - type = xref_tag (class_key, id, attributes, /*globalize=*/0); + type = xref_tag (class_key, id, attributes, /*globalize=*/false, + parser->num_template_parameter_lists); } else { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ef6592a..d2e6bf3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3431,33 +3431,15 @@ convert_template_argument (tree parm, requires_type = (TREE_CODE (parm) == TYPE_DECL || requires_tmpl_type); - if (TREE_CODE (arg) != RECORD_TYPE) - is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL - && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) - || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM - || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE); - else if (CLASSTYPE_TEMPLATE_INFO (arg) && !CLASSTYPE_USE_TEMPLATE (arg) - && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg))) - { - if (is_base_of_enclosing_class (arg, current_class_type)) - /* This is a template name used within the scope of the - template. It could be the template, or it could be the - instantiation. Choose whichever makes sense. */ - is_tmpl_type = requires_tmpl_type; - else - is_tmpl_type = 1; - } - else - /* It is a non-template class, or a specialization of a template - class, or a non-template member of a template class. */ - is_tmpl_type = 0; + is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL + && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) + || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM + || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE); if (is_tmpl_type && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)) arg = TYPE_STUB_DECL (arg); - else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE) - arg = CLASSTYPE_TI_TEMPLATE (arg); is_type = TYPE_P (arg) || is_tmpl_type; diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index baaff74..5e3437f 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -120,7 +120,7 @@ init_rtti_processing (void) push_namespace (std_identifier); type_info_type_node = xref_tag (class_type, get_identifier ("type_info"), - /*attributes=*/NULL_TREE, 1); + /*attributes=*/NULL_TREE, true, false); pop_namespace (); const_type_info_type = build_qualified_type (type_info_type_node, TYPE_QUAL_CONST); @@ -639,7 +639,7 @@ build_dynamic_cast_1 (tree type, tree expr) tinfo_ptr = xref_tag (class_type, get_identifier ("__class_type_info"), /*attributes=*/NULL_TREE, - 1); + true, false); tinfo_ptr = build_pointer_type (build_qualified_type @@ -774,7 +774,7 @@ tinfo_base_init (tree desc, tree target) push_nested_namespace (abi_node); real_type = xref_tag (class_type, TINFO_REAL_NAME (desc), - /*attributes=*/NULL_TREE, 1); + /*attributes=*/NULL_TREE, true, false); pop_nested_namespace (abi_node); if (!COMPLETE_TYPE_P (real_type)) @@ -1371,7 +1371,7 @@ emit_support_tinfos (void) bltn_type = xref_tag (class_type, get_identifier ("__fundamental_type_info"), /*attributes=*/NULL_TREE, - 1); + true, false); pop_nested_namespace (abi_node); if (!COMPLETE_TYPE_P (bltn_type)) return; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 28e6e20..8b96d84 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2003-08-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/8442, c++/8806 + * g++.dg/template/elab1.C: New test. + * g++.dg/template/type2.C: Likewise. + * g++.dg/template/ttp3.C: Adjust expected error message. + * g++.old-deja/g++.law/visibility13.C: Likewise. + * g++.old-deja/g++.niklas/t135.C: Likewise. + * g++.old-deja/g++.pt/ttp41.C: Likewise. + * g++.old-deja/g++.pt/ttp43.C: Use qualified name for template + template argument. + * g++.old-deja/g++.pt/ttp44.C: Likewise. + 2003-08-01 Nathan Sidwell <nathan@codesourcery.com> PR c++/11295 diff --git a/gcc/testsuite/g++.dg/template/elab1.C b/gcc/testsuite/g++.dg/template/elab1.C new file mode 100644 index 0000000..778150f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/elab1.C @@ -0,0 +1,13 @@ +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +// Elaborate type specifier of class template + +template <class T> class A { + class B; +}; + +template <class T> class A<T>::B { + friend class A; +}; diff --git a/gcc/testsuite/g++.dg/template/ttp3.C b/gcc/testsuite/g++.dg/template/ttp3.C index 05bd44a..cc3128c 100644 --- a/gcc/testsuite/g++.dg/template/ttp3.C +++ b/gcc/testsuite/g++.dg/template/ttp3.C @@ -14,13 +14,13 @@ class OUTER { template <class T> class List { }; - vector<class List> data; // { dg-error "type/value mismatch|expected a type|ISO C" "" } + vector<class List> data; // { dg-error "invalid|required|ISO C" "" } }; template <class T> -class List { }; // { dg-bogus "previous declaration" "" { xfail *-*-* } } +class List { }; // This next line should just do a lookup of 'class List', and then // get a type/value mismatch. Instead we try and push 'class List' // into the global namespace and get a redeclaration error. -vector<class List > data; // { dg-bogus "`struct List' redeclared|type/value mismatch" "" { xfail *-*-* } } +vector<class List > data; // { dg-error "invalid|required|expected" "" } diff --git a/gcc/testsuite/g++.dg/template/type2.C b/gcc/testsuite/g++.dg/template/type2.C new file mode 100644 index 0000000..509c482 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/type2.C @@ -0,0 +1,16 @@ +// { dg-do compile } +// Origin: Juan Carlos Arevalo-Baeza <jcab@JCABs-Rumblings.com> + +// PR c++/8442 +// Type template parameter incorrectly treated as template template +// parameter. + +template <typename T> struct A {}; + +template <typename T> struct B +{ + template <typename U> struct C {}; + template <typename U> A<C<U> > foo(U); +}; + +B<void> b; diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility13.C b/gcc/testsuite/g++.old-deja/g++.law/visibility13.C index 4ea561b..025b0b1 100644 --- a/gcc/testsuite/g++.old-deja/g++.law/visibility13.C +++ b/gcc/testsuite/g++.old-deja/g++.law/visibility13.C @@ -65,7 +65,7 @@ void Array<Type>::init(const Type *array, int sz) // --------------- Array_RC.h && Array_RC.cc ---------------- template <class Type> -class Array_RC : public Array<Type> {// { dg-error "" } previous declaration.* +class Array_RC : public Array<Type> { public: Array_RC(const Type *ar, int sz); Type& operator[](int ix); diff --git a/gcc/testsuite/g++.old-deja/g++.niklas/t135.C b/gcc/testsuite/g++.old-deja/g++.niklas/t135.C index 5e826f1..566b0ca 100644 --- a/gcc/testsuite/g++.old-deja/g++.niklas/t135.C +++ b/gcc/testsuite/g++.old-deja/g++.niklas/t135.C @@ -1,7 +1,7 @@ -// { dg-do assemble } +// { dg-do compile } // GROUPS niklas pt friend template <class T> class C1 -{ // { dg-error "" } +{ public: void diddle_C2 (); }; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp41.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp41.C index 18a3322..b260961 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/ttp41.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/ttp41.C @@ -1,4 +1,4 @@ -// { dg-do run } +// { dg-do compile } template<template<class> class D,class E> class C { public: @@ -13,8 +13,8 @@ template<class T> class D template<class T> int D<T>::f() { - C<D,D> c; - return c.g(); + C<D,D> c; // { dg-error "" } + return c.g(); // { dg-error "" } } int main() diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp43.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp43.C index d18a4eb..e1bc4ce 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/ttp43.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/ttp43.C @@ -20,11 +20,11 @@ struct Lit { template < class T > struct Id { - Add < T, Id, Lit > operator+(const T& t) const { - return Add < T, Id, Lit >(*this, Lit<T>(t)); + Add < T, ::Id, Lit > operator+(const T& t) const { + return Add < T, ::Id, Lit >(*this, Lit<T>(t)); } - Mul < T, Id, Lit > operator*(const T& t) const { - return Mul < T, Id, Lit >(*this, Lit<T>(t)); + Mul < T, ::Id, Lit > operator*(const T& t) const { + return Mul < T, ::Id, Lit >(*this, Lit<T>(t)); } }; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp44.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp44.C index f977fcb..08eb307 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/ttp44.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/ttp44.C @@ -9,8 +9,8 @@ public: template < class T > struct Id { template < template < class > class E > - Add < T, Id, E > operator+(const E<T>& e) const { - return Add < T, Id, E >(*this, e); + Add < T, ::Id, E > operator+(const E<T>& e) const { + return Add < T, ::Id, E >(*this, e); } }; |