Commit d85d3d57 by Mark Mitchell Committed by Mark Mitchell

re PR c++/25439 ("template<> int A<0>" accepted)

	PR c++/25439
	* decl.c (grokdeclarator): Remove dead code.
	* ptree.c (cxx_print_xnode): Handle BASELINK.
	* parser.c (make_id_declarator): Add sfk parameter.  
	(cp_parser_direct_declarator): Do not pass TYPE_DECLs to
	make_id_declarator.
	(cp_parser_declarator_id): Simplify BASELINKs here.
	(cp_parser_member_declaration): Adjust calls to
	make_id_declarator.
	PR c++/25439
	* g++.dg/parse/crash17.C: Adjust error markers.
	* g++.dg/template/error20.C: New test.

From-SVN: r109079
parent dec2f881
2005-12-26 Mark Mitchell <mark@codesourcery.com> 2005-12-26 Mark Mitchell <mark@codesourcery.com>
PR c++/25439
* decl.c (grokdeclarator): Remove dead code.
* ptree.c (cxx_print_xnode): Handle BASELINK.
* parser.c (make_id_declarator): Add sfk parameter.
(cp_parser_direct_declarator): Do not pass TYPE_DECLs to
make_id_declarator.
(cp_parser_declarator_id): Simplify BASELINKs here.
(cp_parser_member_declaration): Adjust calls to
make_id_declarator.
2005-12-26 Mark Mitchell <mark@codesourcery.com>
PR c++/23171, c++/23172, c++/25417. PR c++/23171, c++/23172, c++/25417.
* typeck.c (build_unary_op): Create temporary variables for * typeck.c (build_unary_op): Create temporary variables for
compound literals whose addresses are taken. compound literals whose addresses are taken.
......
...@@ -6725,10 +6725,6 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -6725,10 +6725,6 @@ grokdeclarator (const cp_declarator *declarator,
else if (TREE_CODE (qualifying_scope) == NAMESPACE_DECL) else if (TREE_CODE (qualifying_scope) == NAMESPACE_DECL)
in_namespace = qualifying_scope; in_namespace = qualifying_scope;
} }
if (TREE_CODE (decl) == BASELINK)
decl = BASELINK_FUNCTIONS (decl);
if (decl == error_mark_node)
return error_mark_node;
switch (TREE_CODE (decl)) switch (TREE_CODE (decl))
{ {
case BIT_NOT_EXPR: case BIT_NOT_EXPR:
...@@ -6792,11 +6788,6 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -6792,11 +6788,6 @@ grokdeclarator (const cp_declarator *declarator,
} }
break; break;
case TYPE_DECL:
dname = constructor_name (TREE_TYPE (decl));
name = IDENTIFIER_POINTER (dname);
break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
...@@ -7262,8 +7253,6 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -7262,8 +7253,6 @@ grokdeclarator (const cp_declarator *declarator,
else else
{ {
unqualified_id = id_declarator->u.id.unqualified_name; unqualified_id = id_declarator->u.id.unqualified_name;
if (TREE_CODE (unqualified_id) == BASELINK)
unqualified_id = BASELINK_FUNCTIONS (unqualified_id);
switch (TREE_CODE (unqualified_id)) switch (TREE_CODE (unqualified_id))
{ {
case BIT_NOT_EXPR: case BIT_NOT_EXPR:
...@@ -7271,11 +7260,6 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -7271,11 +7260,6 @@ grokdeclarator (const cp_declarator *declarator,
= constructor_name (TREE_OPERAND (unqualified_id, 0)); = constructor_name (TREE_OPERAND (unqualified_id, 0));
break; break;
case TYPE_DECL:
unqualified_id
= constructor_name (TREE_TYPE (unqualified_id));
break;
case IDENTIFIER_NODE: case IDENTIFIER_NODE:
case TEMPLATE_ID_EXPR: case TEMPLATE_ID_EXPR:
break; break;
......
...@@ -833,12 +833,15 @@ make_declarator (cp_declarator_kind kind) ...@@ -833,12 +833,15 @@ make_declarator (cp_declarator_kind kind)
return declarator; return declarator;
} }
/* Make a declarator for a generalized identifier. If non-NULL, the /* Make a declarator for a generalized identifier. If
identifier is QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is QUALIFYING_SCOPE is non-NULL, the identifier is
just UNQUALIFIED_NAME. */ QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is just
UNQUALIFIED_NAME. SFK indicates the kind of special function this
is, if any. */
static cp_declarator * static cp_declarator *
make_id_declarator (tree qualifying_scope, tree unqualified_name) make_id_declarator (tree qualifying_scope, tree unqualified_name,
special_function_kind sfk)
{ {
cp_declarator *declarator; cp_declarator *declarator;
...@@ -855,10 +858,14 @@ make_id_declarator (tree qualifying_scope, tree unqualified_name) ...@@ -855,10 +858,14 @@ make_id_declarator (tree qualifying_scope, tree unqualified_name)
if (qualifying_scope && TYPE_P (qualifying_scope)) if (qualifying_scope && TYPE_P (qualifying_scope))
qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope); qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope);
gcc_assert (TREE_CODE (unqualified_name) == IDENTIFIER_NODE
|| TREE_CODE (unqualified_name) == BIT_NOT_EXPR
|| TREE_CODE (unqualified_name) == TEMPLATE_ID_EXPR);
declarator = make_declarator (cdk_id); declarator = make_declarator (cdk_id);
declarator->u.id.qualifying_scope = qualifying_scope; declarator->u.id.qualifying_scope = qualifying_scope;
declarator->u.id.unqualified_name = unqualified_name; declarator->u.id.unqualified_name = unqualified_name;
declarator->u.id.sfk = sfk_none; declarator->u.id.sfk = sfk;
return declarator; return declarator;
} }
...@@ -11354,6 +11361,7 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -11354,6 +11361,7 @@ cp_parser_direct_declarator (cp_parser* parser,
{ {
tree qualifying_scope; tree qualifying_scope;
tree unqualified_name; tree unqualified_name;
special_function_kind sfk;
/* Parse a declarator-id */ /* Parse a declarator-id */
if (dcl_kind == CP_PARSER_DECLARATOR_EITHER) if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
...@@ -11411,9 +11419,7 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -11411,9 +11419,7 @@ cp_parser_direct_declarator (cp_parser* parser,
qualifying_scope = type; qualifying_scope = type;
} }
declarator = make_id_declarator (qualifying_scope, sfk = sfk_none;
unqualified_name);
declarator->id_loc = token->location;
if (unqualified_name) if (unqualified_name)
{ {
tree class_type; tree class_type;
...@@ -11424,28 +11430,9 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -11424,28 +11430,9 @@ cp_parser_direct_declarator (cp_parser* parser,
else else
class_type = current_class_type; class_type = current_class_type;
if (class_type) if (TREE_CODE (unqualified_name) == TYPE_DECL)
{ {
if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
declarator->u.id.sfk = sfk_destructor;
else if (IDENTIFIER_TYPENAME_P (unqualified_name))
declarator->u.id.sfk = sfk_conversion;
else if (/* There's no way to declare a constructor
for an anonymous type, even if the type
got a name for linkage purposes. */
!TYPE_WAS_ANONYMOUS (class_type)
&& (constructor_name_p (unqualified_name,
class_type)
|| (TREE_CODE (unqualified_name) == TYPE_DECL
&& (same_type_p
(TREE_TYPE (unqualified_name),
class_type)))))
declarator->u.id.sfk = sfk_constructor;
if (ctor_dtor_or_conv_p && declarator->u.id.sfk != sfk_none)
*ctor_dtor_or_conv_p = -1;
if (qualifying_scope if (qualifying_scope
&& TREE_CODE (unqualified_name) == TYPE_DECL
&& CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name))) && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name)))
{ {
error ("invalid use of constructor as a template"); error ("invalid use of constructor as a template");
...@@ -11454,10 +11441,51 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -11454,10 +11441,51 @@ cp_parser_direct_declarator (cp_parser* parser,
class_type, class_type,
DECL_NAME (TYPE_TI_TEMPLATE (class_type)), DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
class_type, class_type); class_type, class_type);
declarator = cp_error_declarator;
break;
} }
else if (class_type
&& same_type_p (TREE_TYPE (unqualified_name),
class_type))
unqualified_name = constructor_name (class_type);
else
{
/* We do not attempt to print the declarator
here because we do not have enough
information about its original syntactic
form. */
error ("invalid declarator");
declarator = cp_error_declarator;
break;
} }
} }
if (class_type)
{
if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
sfk = sfk_destructor;
else if (IDENTIFIER_TYPENAME_P (unqualified_name))
sfk = sfk_conversion;
else if (/* There's no way to declare a constructor
for an anonymous type, even if the type
got a name for linkage purposes. */
!TYPE_WAS_ANONYMOUS (class_type)
&& constructor_name_p (unqualified_name,
class_type))
{
unqualified_name = constructor_name (class_type);
sfk = sfk_constructor;
}
if (ctor_dtor_or_conv_p && sfk != sfk_none)
*ctor_dtor_or_conv_p = -1;
}
}
declarator = make_id_declarator (qualifying_scope,
unqualified_name,
sfk);
declarator->id_loc = token->location;
handle_declarator:; handle_declarator:;
scope = get_scope_of_declarator (declarator); scope = get_scope_of_declarator (declarator);
if (scope) if (scope)
...@@ -11666,6 +11694,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser) ...@@ -11666,6 +11694,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
static tree static tree
cp_parser_declarator_id (cp_parser* parser) cp_parser_declarator_id (cp_parser* parser)
{ {
tree id;
/* The expression must be an id-expression. Assume that qualified /* The expression must be an id-expression. Assume that qualified
names are the names of types so that: names are the names of types so that:
...@@ -11680,11 +11709,14 @@ cp_parser_declarator_id (cp_parser* parser) ...@@ -11680,11 +11709,14 @@ cp_parser_declarator_id (cp_parser* parser)
int S<T>::R<T>::i = 3; int S<T>::R<T>::i = 3;
will work, too. */ will work, too. */
return cp_parser_id_expression (parser, id = cp_parser_id_expression (parser,
/*template_keyword_p=*/false, /*template_keyword_p=*/false,
/*check_dependency_p=*/false, /*check_dependency_p=*/false,
/*template_p=*/NULL, /*template_p=*/NULL,
/*declarator_p=*/true); /*declarator_p=*/true);
if (BASELINK_P (id))
id = BASELINK_FUNCTIONS (id);
return id;
} }
/* Parse a type-id. /* Parse a type-id.
...@@ -13464,7 +13496,8 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -13464,7 +13496,8 @@ cp_parser_member_declaration (cp_parser* parser)
/* Create the bitfield declaration. */ /* Create the bitfield declaration. */
decl = grokbitfield (identifier decl = grokbitfield (identifier
? make_id_declarator (NULL_TREE, ? make_id_declarator (NULL_TREE,
identifier) identifier,
sfk_none)
: NULL, : NULL,
&decl_specifiers, &decl_specifiers,
width); width);
...@@ -17095,7 +17128,8 @@ cp_parser_objc_class_ivars (cp_parser* parser) ...@@ -17095,7 +17128,8 @@ cp_parser_objc_class_ivars (cp_parser* parser)
{ {
/* Get the name of the bitfield. */ /* Get the name of the bitfield. */
declarator = make_id_declarator (NULL_TREE, declarator = make_id_declarator (NULL_TREE,
cp_parser_identifier (parser)); cp_parser_identifier (parser),
sfk_none);
eat_colon: eat_colon:
cp_lexer_consume_token (parser->lexer); /* Eat ':'. */ cp_lexer_consume_token (parser->lexer); /* Eat ':'. */
......
...@@ -169,6 +169,12 @@ cxx_print_xnode (FILE *file, tree node, int indent) ...@@ -169,6 +169,12 @@ cxx_print_xnode (FILE *file, tree node, int indent)
{ {
switch (TREE_CODE (node)) switch (TREE_CODE (node))
{ {
case BASELINK:
print_node (file, "functions", BASELINK_FUNCTIONS (node), indent + 4);
print_node (file, "binfo", BASELINK_BINFO (node), indent + 4);
print_node (file, "access_binfo", BASELINK_ACCESS_BINFO (node),
indent + 4);
break;
case OVERLOAD: case OVERLOAD:
print_node (file, "function", OVL_FUNCTION (node), indent+4); print_node (file, "function", OVL_FUNCTION (node), indent+4);
print_node (file, "chain", TREE_CHAIN (node), indent+4); print_node (file, "chain", TREE_CHAIN (node), indent+4);
......
2005-12-26 Mark Mitchell <mark@codesourcery.com> 2005-12-26 Mark Mitchell <mark@codesourcery.com>
PR c++/25439
* g++.dg/parse/crash17.C: Adjust error markers.
* g++.dg/template/error20.C: New test.
2005-12-26 Mark Mitchell <mark@codesourcery.com>
PR c++/23172 PR c++/23172
* g++.dg/ext/complit4.C: New test. * g++.dg/ext/complit4.C: New test.
...@@ -5,5 +5,5 @@ template <typename> class allocator; ...@@ -5,5 +5,5 @@ template <typename> class allocator;
template<typename T> class vector { template<typename T> class vector {
// With the dg-error on the next line, we are really just trying to // With the dg-error on the next line, we are really just trying to
// check that the message is not an ICE message. // check that the message is not an ICE message.
typedef typename allocator<T> allocator_type; // { dg-error "expected|forbids" } typedef typename allocator<T> allocator_type; // { dg-error "expected|invalid" }
}; };
// PR c++/25439
template<int> struct A;
template<> int A<0>; // { dg-error "invalid" }
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