Commit b0bc6e8e by Kriang Lerdsuwanakij Committed by Kriang Lerdsuwanakij

re PR c++/13520 (gcc crashes with inheritance + default template parameter of nested template type)

	PR c++/13520
	* cp-tree.h (DECL_UNBOUND_CLASS_TEMPLATE_P): New macro.
	(DECL_FUNCTION_TEMPLATE_P): Use it.
	(DECL_CLASS_TEMPLATE_P): Likewise.
	* parser.c (cp_parser_lookup_name): Add is_template parameter.
	(cp_parser_type_parameter): Adjust call to cp_parser_lookup_name.
	(cp_parser_template_name): Likewise.
	(cp_parser_elaborated_type_specifier): Likewise.
	(cp_parser_namespace_name): Likewise.
	(cp_parser_class_name): Likewise.
	(cp_parser_lookup_name_simple): Likewise.

	* g++.dg/template/qualttp22.C: New test.

From-SVN: r75321
parent daef8bbd
2004-01-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/13520
* cp-tree.h (DECL_UNBOUND_CLASS_TEMPLATE_P): New macro.
(DECL_FUNCTION_TEMPLATE_P): Use it.
(DECL_CLASS_TEMPLATE_P): Likewise.
* parser.c (cp_parser_lookup_name): Add is_template parameter.
(cp_parser_type_parameter): Adjust call to cp_parser_lookup_name.
(cp_parser_template_name): Likewise.
(cp_parser_elaborated_type_specifier): Likewise.
(cp_parser_namespace_name): Likewise.
(cp_parser_class_name): Likewise.
(cp_parser_lookup_name_simple): Likewise.
See ChangeLog.3 for earlier changes. See ChangeLog.3 for earlier changes.
/* Definitions for C++ parsing and type checking. /* Definitions for C++ parsing and type checking.
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003 Free Software Foundation, Inc. 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC. This file is part of GCC.
...@@ -2720,13 +2720,20 @@ struct lang_decl GTY(()) ...@@ -2720,13 +2720,20 @@ struct lang_decl GTY(())
#define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \ #define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE)) (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE))
/* Nonzero if NODE is a TEMPLATE_DECL representing an
UNBOUND_CLASS_TEMPLATE tree node. */
#define DECL_UNBOUND_CLASS_TEMPLATE_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL && !DECL_TEMPLATE_RESULT (NODE))
#define DECL_FUNCTION_TEMPLATE_P(NODE) \ #define DECL_FUNCTION_TEMPLATE_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL \ (TREE_CODE (NODE) == TEMPLATE_DECL \
&& !DECL_UNBOUND_CLASS_TEMPLATE_P (NODE) \
&& TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL) && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL)
/* Nonzero for a DECL that represents a template class. */ /* Nonzero for a DECL that represents a template class. */
#define DECL_CLASS_TEMPLATE_P(NODE) \ #define DECL_CLASS_TEMPLATE_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL \ (TREE_CODE (NODE) == TEMPLATE_DECL \
&& !DECL_UNBOUND_CLASS_TEMPLATE_P (NODE) \
&& TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == TYPE_DECL \ && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == TYPE_DECL \
&& !DECL_TEMPLATE_TEMPLATE_PARM_P (NODE)) && !DECL_TEMPLATE_TEMPLATE_PARM_P (NODE))
......
/* C++ Parser. /* C++ Parser.
Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>. Written by Mark Mitchell <mark@codesourcery.com>.
This file is part of GCC. This file is part of GCC.
...@@ -1621,7 +1621,7 @@ static void cp_parser_label_declaration ...@@ -1621,7 +1621,7 @@ static void cp_parser_label_declaration
/* Utility Routines */ /* Utility Routines */
static tree cp_parser_lookup_name static tree cp_parser_lookup_name
(cp_parser *, tree, bool, bool, bool); (cp_parser *, tree, bool, bool, bool, bool);
static tree cp_parser_lookup_name_simple static tree cp_parser_lookup_name_simple
(cp_parser *, tree); (cp_parser *, tree);
static tree cp_parser_maybe_treat_template_as_class static tree cp_parser_maybe_treat_template_as_class
...@@ -7660,6 +7660,8 @@ cp_parser_type_parameter (cp_parser* parser) ...@@ -7660,6 +7660,8 @@ cp_parser_type_parameter (cp_parser* parser)
default-argument. */ default-argument. */
if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
{ {
bool is_template;
/* Consume the `='. */ /* Consume the `='. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* Parse the id-expression. */ /* Parse the id-expression. */
...@@ -7667,11 +7669,15 @@ cp_parser_type_parameter (cp_parser* parser) ...@@ -7667,11 +7669,15 @@ cp_parser_type_parameter (cp_parser* parser)
= cp_parser_id_expression (parser, = cp_parser_id_expression (parser,
/*template_keyword_p=*/false, /*template_keyword_p=*/false,
/*check_dependency_p=*/true, /*check_dependency_p=*/true,
/*template_p=*/NULL, /*template_p=*/&is_template,
/*declarator_p=*/false); /*declarator_p=*/false);
/* Look up the name. */ /* Look up the name. */
default_argument default_argument
= cp_parser_lookup_name_simple (parser, default_argument); = cp_parser_lookup_name (parser, default_argument,
/*is_type=*/false,
/*is_template=*/is_template,
/*is_namespace=*/false,
/*check_dependency=*/true);
/* See if the default argument is valid. */ /* See if the default argument is valid. */
default_argument default_argument
= check_template_template_default_arg (default_argument); = check_template_template_default_arg (default_argument);
...@@ -7979,6 +7985,7 @@ cp_parser_template_name (cp_parser* parser, ...@@ -7979,6 +7985,7 @@ cp_parser_template_name (cp_parser* parser,
/* Look up the name. */ /* Look up the name. */
decl = cp_parser_lookup_name (parser, identifier, decl = cp_parser_lookup_name (parser, identifier,
/*is_type=*/false, /*is_type=*/false,
/*is_template=*/false,
/*is_namespace=*/false, /*is_namespace=*/false,
check_dependency_p); check_dependency_p);
decl = maybe_get_template_decl_from_type_decl (decl); decl = maybe_get_template_decl_from_type_decl (decl);
...@@ -8934,6 +8941,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ...@@ -8934,6 +8941,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
cp_parser_lookup_name. */ cp_parser_lookup_name. */
decl = cp_parser_lookup_name (parser, identifier, decl = cp_parser_lookup_name (parser, identifier,
/*is_type=*/true, /*is_type=*/true,
/*is_template=*/false,
/*is_namespace=*/false, /*is_namespace=*/false,
/*check_dependency=*/true); /*check_dependency=*/true);
...@@ -9206,6 +9214,7 @@ cp_parser_namespace_name (cp_parser* parser) ...@@ -9206,6 +9214,7 @@ cp_parser_namespace_name (cp_parser* parser)
operator.) */ operator.) */
namespace_decl = cp_parser_lookup_name (parser, identifier, namespace_decl = cp_parser_lookup_name (parser, identifier,
/*is_type=*/false, /*is_type=*/false,
/*is_template=*/false,
/*is_namespace=*/true, /*is_namespace=*/true,
/*check_dependency=*/true); /*check_dependency=*/true);
/* If it's not a namespace, issue an error. */ /* If it's not a namespace, issue an error. */
...@@ -11414,6 +11423,7 @@ cp_parser_class_name (cp_parser *parser, ...@@ -11414,6 +11423,7 @@ cp_parser_class_name (cp_parser *parser,
/* Look up the name. */ /* Look up the name. */
decl = cp_parser_lookup_name (parser, identifier, decl = cp_parser_lookup_name (parser, identifier,
type_p, type_p,
/*is_template=*/false,
/*is_namespace=*/false, /*is_namespace=*/false,
check_dependency_p); check_dependency_p);
} }
...@@ -13245,6 +13255,9 @@ cp_parser_label_declaration (cp_parser* parser) ...@@ -13245,6 +13255,9 @@ cp_parser_label_declaration (cp_parser* parser)
If IS_TYPE is TRUE, bindings that do not refer to types are If IS_TYPE is TRUE, bindings that do not refer to types are
ignored. ignored.
If IS_TEMPLATE is TRUE, bindings that do not refer to templates are
ignored.
If IS_NAMESPACE is TRUE, bindings that do not refer to namespaces If IS_NAMESPACE is TRUE, bindings that do not refer to namespaces
are ignored. are ignored.
...@@ -13253,7 +13266,8 @@ cp_parser_label_declaration (cp_parser* parser) ...@@ -13253,7 +13266,8 @@ cp_parser_label_declaration (cp_parser* parser)
static tree static tree
cp_parser_lookup_name (cp_parser *parser, tree name, cp_parser_lookup_name (cp_parser *parser, tree name,
bool is_type, bool is_namespace, bool check_dependency) bool is_type, bool is_template, bool is_namespace,
bool check_dependency)
{ {
tree decl; tree decl;
tree object_type = parser->context->object_type; tree object_type = parser->context->object_type;
...@@ -13325,15 +13339,19 @@ cp_parser_lookup_name (cp_parser *parser, tree name, ...@@ -13325,15 +13339,19 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
if ((check_dependency || !CLASS_TYPE_P (parser->scope)) if ((check_dependency || !CLASS_TYPE_P (parser->scope))
&& dependent_p) && dependent_p)
{ {
if (!is_type) if (is_type)
decl = build_nt (SCOPE_REF, parser->scope, name);
else
/* The resolution to Core Issue 180 says that `struct A::B' /* The resolution to Core Issue 180 says that `struct A::B'
should be considered a type-name, even if `A' is should be considered a type-name, even if `A' is
dependent. */ dependent. */
decl = TYPE_NAME (make_typename_type (parser->scope, decl = TYPE_NAME (make_typename_type (parser->scope,
name, name,
/*complain=*/1)); /*complain=*/1));
else if (is_template)
decl = TYPE_NAME (make_unbound_class_template (parser->scope,
name,
/*complain=*/1));
else
decl = build_nt (SCOPE_REF, parser->scope, name);
} }
else else
{ {
...@@ -13427,14 +13445,15 @@ cp_parser_lookup_name (cp_parser *parser, tree name, ...@@ -13427,14 +13445,15 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
} }
/* Like cp_parser_lookup_name, but for use in the typical case where /* Like cp_parser_lookup_name, but for use in the typical case where
CHECK_ACCESS is TRUE, IS_TYPE is FALSE, and CHECK_DEPENDENCY is CHECK_ACCESS is TRUE, IS_TYPE is FALSE, IS_TEMPLATE is FALSE,
TRUE. */ IS_NAMESPACE is FALSE, and CHECK_DEPENDENCY is TRUE. */
static tree static tree
cp_parser_lookup_name_simple (cp_parser* parser, tree name) cp_parser_lookup_name_simple (cp_parser* parser, tree name)
{ {
return cp_parser_lookup_name (parser, name, return cp_parser_lookup_name (parser, name,
/*is_type=*/false, /*is_type=*/false,
/*is_template=*/false,
/*is_namespace=*/false, /*is_namespace=*/false,
/*check_dependency=*/true); /*check_dependency=*/true);
} }
......
2004-01-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/13520
* g++.dg/template/qualttp22.C: New test.
2004-01-01 Jan Hubicka <jh@suse.cz> 2004-01-01 Jan Hubicka <jh@suse.cz>
* gcc.dg/debug/20031231-1.c: New. * gcc.dg/debug/20031231-1.c: New.
......
// { dg-do compile }
// Origin: Philippe Van Deyck <hetadres@email.com>
// PR c++/13520: Default template template argument that is a qualified id
// with dependent scope.
template<typename regular_type> class Policy {};
template <typename regular_type, template<typename> class OriginalPolicy>
class ChangedPolicy_impl {};
template <template<typename> class OriginalPolicy > class ChangedPolicy {
public:
template<typename regular_type> class Type : public
ChangedPolicy_impl<regular_type,OriginalPolicy> { };
};
template <typename regular_type, template<typename> class Policy1,
template<typename> class Policy2
= ChangedPolicy<Policy1>::template Type>
class Host : public Policy1<regular_type>, public Policy2<regular_type> { };
int main()
{
Host<void, Policy> h;
return 0;
}
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