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>
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.
* typeck.c (build_unary_op): Create temporary variables for
compound literals whose addresses are taken.
......
......@@ -6725,10 +6725,6 @@ grokdeclarator (const cp_declarator *declarator,
else if (TREE_CODE (qualifying_scope) == NAMESPACE_DECL)
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))
{
case BIT_NOT_EXPR:
......@@ -6792,11 +6788,6 @@ grokdeclarator (const cp_declarator *declarator,
}
break;
case TYPE_DECL:
dname = constructor_name (TREE_TYPE (decl));
name = IDENTIFIER_POINTER (dname);
break;
default:
gcc_unreachable ();
}
......@@ -7262,8 +7253,6 @@ grokdeclarator (const cp_declarator *declarator,
else
{
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))
{
case BIT_NOT_EXPR:
......@@ -7271,11 +7260,6 @@ grokdeclarator (const cp_declarator *declarator,
= constructor_name (TREE_OPERAND (unqualified_id, 0));
break;
case TYPE_DECL:
unqualified_id
= constructor_name (TREE_TYPE (unqualified_id));
break;
case IDENTIFIER_NODE:
case TEMPLATE_ID_EXPR:
break;
......
......@@ -833,12 +833,15 @@ make_declarator (cp_declarator_kind kind)
return declarator;
}
/* Make a declarator for a generalized identifier. If non-NULL, the
identifier is QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is
just UNQUALIFIED_NAME. */
/* Make a declarator for a generalized identifier. If
QUALIFYING_SCOPE is non-NULL, the identifier is
QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is just
UNQUALIFIED_NAME. SFK indicates the kind of special function this
is, if any. */
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;
......@@ -855,10 +858,14 @@ make_id_declarator (tree qualifying_scope, tree unqualified_name)
if (qualifying_scope && TYPE_P (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->u.id.qualifying_scope = qualifying_scope;
declarator->u.id.unqualified_name = unqualified_name;
declarator->u.id.sfk = sfk_none;
declarator->u.id.sfk = sfk;
return declarator;
}
......@@ -11354,6 +11361,7 @@ cp_parser_direct_declarator (cp_parser* parser,
{
tree qualifying_scope;
tree unqualified_name;
special_function_kind sfk;
/* Parse a declarator-id */
if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
......@@ -11411,9 +11419,7 @@ cp_parser_direct_declarator (cp_parser* parser,
qualifying_scope = type;
}
declarator = make_id_declarator (qualifying_scope,
unqualified_name);
declarator->id_loc = token->location;
sfk = sfk_none;
if (unqualified_name)
{
tree class_type;
......@@ -11424,28 +11430,9 @@ cp_parser_direct_declarator (cp_parser* parser,
else
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
&& TREE_CODE (unqualified_name) == TYPE_DECL
if (qualifying_scope
&& CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name)))
{
error ("invalid use of constructor as a template");
......@@ -11454,9 +11441,50 @@ cp_parser_direct_declarator (cp_parser* parser,
class_type,
DECL_NAME (TYPE_TI_TEMPLATE (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:;
scope = get_scope_of_declarator (declarator);
......@@ -11666,6 +11694,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
static tree
cp_parser_declarator_id (cp_parser* parser)
{
tree id;
/* The expression must be an id-expression. Assume that qualified
names are the names of types so that:
......@@ -11680,11 +11709,14 @@ cp_parser_declarator_id (cp_parser* parser)
int S<T>::R<T>::i = 3;
will work, too. */
return cp_parser_id_expression (parser,
/*template_keyword_p=*/false,
/*check_dependency_p=*/false,
/*template_p=*/NULL,
/*declarator_p=*/true);
id = cp_parser_id_expression (parser,
/*template_keyword_p=*/false,
/*check_dependency_p=*/false,
/*template_p=*/NULL,
/*declarator_p=*/true);
if (BASELINK_P (id))
id = BASELINK_FUNCTIONS (id);
return id;
}
/* Parse a type-id.
......@@ -13464,7 +13496,8 @@ cp_parser_member_declaration (cp_parser* parser)
/* Create the bitfield declaration. */
decl = grokbitfield (identifier
? make_id_declarator (NULL_TREE,
identifier)
identifier,
sfk_none)
: NULL,
&decl_specifiers,
width);
......@@ -17095,7 +17128,8 @@ cp_parser_objc_class_ivars (cp_parser* parser)
{
/* Get the name of the bitfield. */
declarator = make_id_declarator (NULL_TREE,
cp_parser_identifier (parser));
cp_parser_identifier (parser),
sfk_none);
eat_colon:
cp_lexer_consume_token (parser->lexer); /* Eat ':'. */
......
......@@ -169,6 +169,12 @@ cxx_print_xnode (FILE *file, tree node, int indent)
{
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:
print_node (file, "function", OVL_FUNCTION (node), indent+4);
print_node (file, "chain", TREE_CHAIN (node), indent+4);
......
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
* g++.dg/ext/complit4.C: New test.
......@@ -5,5 +5,5 @@ template <typename> class allocator;
template<typename T> class vector {
// With the dg-error on the next line, we are really just trying to
// 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