mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-11 18:45:31 +08:00
re PR c++/23287 (Explicitly invoking destructor of template class in a template and is dependent)
cp/ PR c++/23287 * parser.c (cp_parser_id_expression): Add member_p argument. Update all callers. (cp_parser_unqualified_id): Likewise. Lookup a destructor name in the object's scope, if valid. (cp_parser_global_scope_opt): Add object_scope_valid_p. Update callers. (cp_parser_postfix_dot_deref_expression): Set object_scope. * pt.c (tsubst_copy_and_build): Lookup dependent dtor name here. testsuite/ PR c++/23287 * g++.dg/parse/dtor12.C: New. From-SVN: r116623
This commit is contained in:
parent
39aa3581c4
commit
429b876b07
@ -1,3 +1,15 @@
|
|||||||
|
2006-09-01 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
PR c++/23287
|
||||||
|
* parser.c (cp_parser_id_expression): Add member_p
|
||||||
|
argument. Update all callers.
|
||||||
|
(cp_parser_unqualified_id): Likewise. Lookup a destructor name in
|
||||||
|
the object's scope, if valid.
|
||||||
|
(cp_parser_global_scope_opt): Add object_scope_valid_p. Update
|
||||||
|
callers.
|
||||||
|
(cp_parser_postfix_dot_deref_expression): Set object_scope.
|
||||||
|
* pt.c (tsubst_copy_and_build): Lookup dependent dtor name here.
|
||||||
|
|
||||||
2006-08-30 Jason Merrill <jason@redhat.com>
|
2006-08-30 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
PR c++/26670
|
PR c++/26670
|
||||||
|
149
gcc/cp/parser.c
149
gcc/cp/parser.c
@ -1393,9 +1393,9 @@ static bool cp_parser_translation_unit
|
|||||||
static tree cp_parser_primary_expression
|
static tree cp_parser_primary_expression
|
||||||
(cp_parser *, bool, bool, bool, cp_id_kind *);
|
(cp_parser *, bool, bool, bool, cp_id_kind *);
|
||||||
static tree cp_parser_id_expression
|
static tree cp_parser_id_expression
|
||||||
(cp_parser *, bool, bool, bool *, bool, bool);
|
(cp_parser *, bool, bool, bool *, bool, bool, bool);
|
||||||
static tree cp_parser_unqualified_id
|
static tree cp_parser_unqualified_id
|
||||||
(cp_parser *, bool, bool, bool, bool);
|
(cp_parser *, bool, bool, bool, bool, bool);
|
||||||
static tree cp_parser_nested_name_specifier_opt
|
static tree cp_parser_nested_name_specifier_opt
|
||||||
(cp_parser *, bool, bool, bool, bool);
|
(cp_parser *, bool, bool, bool, bool);
|
||||||
static tree cp_parser_nested_name_specifier
|
static tree cp_parser_nested_name_specifier
|
||||||
@ -1720,7 +1720,7 @@ static bool cp_parser_check_template_parameters
|
|||||||
static tree cp_parser_simple_cast_expression
|
static tree cp_parser_simple_cast_expression
|
||||||
(cp_parser *);
|
(cp_parser *);
|
||||||
static tree cp_parser_global_scope_opt
|
static tree cp_parser_global_scope_opt
|
||||||
(cp_parser *, bool);
|
(cp_parser *, bool, bool);
|
||||||
static bool cp_parser_constructor_declarator_p
|
static bool cp_parser_constructor_declarator_p
|
||||||
(cp_parser *, bool);
|
(cp_parser *, bool);
|
||||||
static tree cp_parser_function_definition_from_specifiers_and_declarator
|
static tree cp_parser_function_definition_from_specifiers_and_declarator
|
||||||
@ -2182,7 +2182,8 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
|
|||||||
/*check_dependency_p=*/true,
|
/*check_dependency_p=*/true,
|
||||||
/*template_p=*/NULL,
|
/*template_p=*/NULL,
|
||||||
/*declarator_p=*/true,
|
/*declarator_p=*/true,
|
||||||
/*optional_p=*/false);
|
/*optional_p=*/false,
|
||||||
|
/*member_p=*/false);
|
||||||
/* After the id-expression, there should be a plain identifier,
|
/* After the id-expression, there should be a plain identifier,
|
||||||
otherwise this is not a simple variable declaration. Also, if
|
otherwise this is not a simple variable declaration. Also, if
|
||||||
the scope is dependent, we cannot do much. */
|
the scope is dependent, we cannot do much. */
|
||||||
@ -3061,7 +3062,8 @@ cp_parser_primary_expression (cp_parser *parser,
|
|||||||
/*check_dependency_p=*/true,
|
/*check_dependency_p=*/true,
|
||||||
&template_p,
|
&template_p,
|
||||||
/*declarator_p=*/false,
|
/*declarator_p=*/false,
|
||||||
/*optional_p=*/false);
|
/*optional_p=*/false,
|
||||||
|
/*member_p=*/false);
|
||||||
if (id_expression == error_mark_node)
|
if (id_expression == error_mark_node)
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
token = cp_lexer_peek_token (parser->lexer);
|
token = cp_lexer_peek_token (parser->lexer);
|
||||||
@ -3195,7 +3197,8 @@ cp_parser_id_expression (cp_parser *parser,
|
|||||||
bool check_dependency_p,
|
bool check_dependency_p,
|
||||||
bool *template_p,
|
bool *template_p,
|
||||||
bool declarator_p,
|
bool declarator_p,
|
||||||
bool optional_p)
|
bool optional_p,
|
||||||
|
bool member_p)
|
||||||
{
|
{
|
||||||
bool global_scope_p;
|
bool global_scope_p;
|
||||||
bool nested_name_specifier_p;
|
bool nested_name_specifier_p;
|
||||||
@ -3206,8 +3209,10 @@ cp_parser_id_expression (cp_parser *parser,
|
|||||||
|
|
||||||
/* Look for the optional `::' operator. */
|
/* Look for the optional `::' operator. */
|
||||||
global_scope_p
|
global_scope_p
|
||||||
= (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false)
|
= (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/member_p)
|
||||||
!= NULL_TREE);
|
!= NULL_TREE);
|
||||||
|
|
||||||
/* Look for the optional nested-name-specifier. */
|
/* Look for the optional nested-name-specifier. */
|
||||||
nested_name_specifier_p
|
nested_name_specifier_p
|
||||||
= (cp_parser_nested_name_specifier_opt (parser,
|
= (cp_parser_nested_name_specifier_opt (parser,
|
||||||
@ -3239,7 +3244,8 @@ cp_parser_id_expression (cp_parser *parser,
|
|||||||
unqualified_id = cp_parser_unqualified_id (parser, *template_p,
|
unqualified_id = cp_parser_unqualified_id (parser, *template_p,
|
||||||
check_dependency_p,
|
check_dependency_p,
|
||||||
declarator_p,
|
declarator_p,
|
||||||
/*optional_p=*/false);
|
/*optional_p=*/false,
|
||||||
|
/*member_p=*/false);
|
||||||
/* Restore the SAVED_SCOPE for our caller. */
|
/* Restore the SAVED_SCOPE for our caller. */
|
||||||
parser->scope = saved_scope;
|
parser->scope = saved_scope;
|
||||||
parser->object_scope = saved_object_scope;
|
parser->object_scope = saved_object_scope;
|
||||||
@ -3297,8 +3303,7 @@ cp_parser_id_expression (cp_parser *parser,
|
|||||||
else
|
else
|
||||||
return cp_parser_unqualified_id (parser, template_keyword_p,
|
return cp_parser_unqualified_id (parser, template_keyword_p,
|
||||||
/*check_dependency_p=*/true,
|
/*check_dependency_p=*/true,
|
||||||
declarator_p,
|
declarator_p, optional_p, member_p);
|
||||||
optional_p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse an unqualified-id.
|
/* Parse an unqualified-id.
|
||||||
@ -3328,7 +3333,8 @@ cp_parser_unqualified_id (cp_parser* parser,
|
|||||||
bool template_keyword_p,
|
bool template_keyword_p,
|
||||||
bool check_dependency_p,
|
bool check_dependency_p,
|
||||||
bool declarator_p,
|
bool declarator_p,
|
||||||
bool optional_p)
|
bool optional_p,
|
||||||
|
bool member_p)
|
||||||
{
|
{
|
||||||
cp_token *token;
|
cp_token *token;
|
||||||
|
|
||||||
@ -3456,6 +3462,7 @@ cp_parser_unqualified_id (cp_parser* parser,
|
|||||||
if (cp_parser_parse_definitely (parser))
|
if (cp_parser_parse_definitely (parser))
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In "N::S::~S", look in "N" as well. */
|
/* In "N::S::~S", look in "N" as well. */
|
||||||
if (!done && scope && qualifying_scope)
|
if (!done && scope && qualifying_scope)
|
||||||
{
|
{
|
||||||
@ -3474,24 +3481,56 @@ cp_parser_unqualified_id (cp_parser* parser,
|
|||||||
if (cp_parser_parse_definitely (parser))
|
if (cp_parser_parse_definitely (parser))
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
/* In "p->S::~T", look in the scope given by "*p" as well. */
|
/* In "p->~T", look in the scope given by "*p" as well. */
|
||||||
else if (!done && object_scope)
|
else if (!done && member_p)
|
||||||
{
|
{
|
||||||
|
if (!object_scope)
|
||||||
|
{
|
||||||
|
/* It's a dependent expression, so just parse the
|
||||||
|
dtor name. */
|
||||||
|
tree id;
|
||||||
|
|
||||||
|
if (template_keyword_p)
|
||||||
|
/* It's a template-id. */
|
||||||
|
id = cp_parser_template_id (parser, true,
|
||||||
|
check_dependency_p,
|
||||||
|
declarator_p);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise, it's an ordinary identifier. */
|
||||||
|
id = cp_parser_identifier (parser);
|
||||||
|
/* If ID is a template type parm, then use that
|
||||||
|
directly. */
|
||||||
|
if (TREE_TYPE (id)
|
||||||
|
&& TREE_CODE (TREE_TYPE (id)) == TEMPLATE_TYPE_PARM)
|
||||||
|
id = TREE_TYPE (id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id != error_mark_node)
|
||||||
|
id = build_nt (BIT_NOT_EXPR, id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
cp_parser_parse_tentatively (parser);
|
cp_parser_parse_tentatively (parser);
|
||||||
parser->scope = object_scope;
|
parser->scope = object_scope;
|
||||||
parser->object_scope = NULL_TREE;
|
parser->object_scope = NULL_TREE;
|
||||||
parser->qualifying_scope = NULL_TREE;
|
parser->qualifying_scope = NULL_TREE;
|
||||||
type_decl
|
type_decl
|
||||||
= cp_parser_class_name (parser,
|
= cp_parser_class_name (parser,
|
||||||
/*typename_keyword_p=*/false,
|
/*typename_keyword_p=*/false,
|
||||||
/*template_keyword_p=*/false,
|
/*template_keyword_p=*/false,
|
||||||
none_type,
|
none_type,
|
||||||
/*check_dependency=*/false,
|
/*check_dependency=*/false,
|
||||||
/*class_head_p=*/false,
|
/*class_head_p=*/false,
|
||||||
declarator_p);
|
declarator_p);
|
||||||
|
/* The name is not qualified, so reset the parser scopes
|
||||||
|
so our callers do not get confused. */
|
||||||
|
parser->object_scope = object_scope;
|
||||||
|
parser->scope = NULL_TREE;
|
||||||
if (cp_parser_parse_definitely (parser))
|
if (cp_parser_parse_definitely (parser))
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look in the surrounding context. */
|
/* Look in the surrounding context. */
|
||||||
if (!done)
|
if (!done)
|
||||||
{
|
{
|
||||||
@ -4482,11 +4521,12 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
|
|||||||
parser->qualifying_scope = NULL_TREE;
|
parser->qualifying_scope = NULL_TREE;
|
||||||
parser->object_scope = NULL_TREE;
|
parser->object_scope = NULL_TREE;
|
||||||
*idk = CP_ID_KIND_NONE;
|
*idk = CP_ID_KIND_NONE;
|
||||||
|
|
||||||
/* Enter the scope corresponding to the type of the object
|
/* Enter the scope corresponding to the type of the object
|
||||||
given by the POSTFIX_EXPRESSION. */
|
given by the POSTFIX_EXPRESSION. */
|
||||||
if (!dependent_p && TREE_TYPE (postfix_expression) != NULL_TREE)
|
scope = TREE_TYPE (postfix_expression);
|
||||||
|
if (!dependent_p && scope)
|
||||||
{
|
{
|
||||||
scope = TREE_TYPE (postfix_expression);
|
|
||||||
/* According to the standard, no expression should ever have
|
/* According to the standard, no expression should ever have
|
||||||
reference type. Unfortunately, we do not currently match
|
reference type. Unfortunately, we do not currently match
|
||||||
the standard in this respect in that our internal representation
|
the standard in this respect in that our internal representation
|
||||||
@ -4500,11 +4540,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
|
|||||||
error ("%qE does not have class type", postfix_expression);
|
error ("%qE does not have class type", postfix_expression);
|
||||||
scope = NULL_TREE;
|
scope = NULL_TREE;
|
||||||
}
|
}
|
||||||
else
|
else if (!dependent_p)
|
||||||
scope = complete_type_or_else (scope, NULL_TREE);
|
scope = complete_type_or_else (scope, NULL_TREE);
|
||||||
/* Let the name lookup machinery know that we are processing a
|
|
||||||
class member access expression. */
|
|
||||||
parser->context->object_type = scope;
|
|
||||||
/* If something went wrong, we want to be able to discern that case,
|
/* If something went wrong, we want to be able to discern that case,
|
||||||
as opposed to the case where there was no SCOPE due to the type
|
as opposed to the case where there was no SCOPE due to the type
|
||||||
of expression being dependent. */
|
of expression being dependent. */
|
||||||
@ -4516,6 +4553,10 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
|
|||||||
if (scope == error_mark_node)
|
if (scope == error_mark_node)
|
||||||
postfix_expression = error_mark_node;
|
postfix_expression = error_mark_node;
|
||||||
}
|
}
|
||||||
|
/* Let the name lookup machinery know that we are processing a class
|
||||||
|
member access expression. */
|
||||||
|
parser->context->object_type = scope;
|
||||||
|
parser->object_scope = scope;
|
||||||
|
|
||||||
/* Assume this expression is not a pseudo-destructor access. */
|
/* Assume this expression is not a pseudo-destructor access. */
|
||||||
pseudo_destructor_p = false;
|
pseudo_destructor_p = false;
|
||||||
@ -4553,7 +4594,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
|
|||||||
/*check_dependency_p=*/true,
|
/*check_dependency_p=*/true,
|
||||||
&template_p,
|
&template_p,
|
||||||
/*declarator_p=*/false,
|
/*declarator_p=*/false,
|
||||||
/*optional_p=*/false));
|
/*optional_p=*/false,
|
||||||
|
/*member_p=*/true));
|
||||||
/* In general, build a SCOPE_REF if the member name is qualified.
|
/* In general, build a SCOPE_REF if the member name is qualified.
|
||||||
However, if the name was not dependent and has already been
|
However, if the name was not dependent and has already been
|
||||||
resolved; there is no need to build the SCOPE_REF. For example;
|
resolved; there is no need to build the SCOPE_REF. For example;
|
||||||
@ -4758,7 +4800,9 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
|
|||||||
*type = error_mark_node;
|
*type = error_mark_node;
|
||||||
|
|
||||||
/* Look for the optional `::' operator. */
|
/* Look for the optional `::' operator. */
|
||||||
cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/true);
|
cp_parser_global_scope_opt (parser,
|
||||||
|
/*current_scope_valid_p=*/true,
|
||||||
|
/*object_scop_valid_p=*/true);
|
||||||
/* Look for the optional nested-name-specifier. */
|
/* Look for the optional nested-name-specifier. */
|
||||||
nested_name_specifier_p
|
nested_name_specifier_p
|
||||||
= (cp_parser_nested_name_specifier_opt (parser,
|
= (cp_parser_nested_name_specifier_opt (parser,
|
||||||
@ -5069,7 +5113,8 @@ cp_parser_new_expression (cp_parser* parser)
|
|||||||
/* Look for the optional `::' operator. */
|
/* Look for the optional `::' operator. */
|
||||||
global_scope_p
|
global_scope_p
|
||||||
= (cp_parser_global_scope_opt (parser,
|
= (cp_parser_global_scope_opt (parser,
|
||||||
/*current_scope_valid_p=*/false)
|
/*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false)
|
||||||
!= NULL_TREE);
|
!= NULL_TREE);
|
||||||
/* Look for the `new' operator. */
|
/* Look for the `new' operator. */
|
||||||
cp_parser_require_keyword (parser, RID_NEW, "`new'");
|
cp_parser_require_keyword (parser, RID_NEW, "`new'");
|
||||||
@ -5367,7 +5412,8 @@ cp_parser_delete_expression (cp_parser* parser)
|
|||||||
/* Look for the optional `::' operator. */
|
/* Look for the optional `::' operator. */
|
||||||
global_scope_p
|
global_scope_p
|
||||||
= (cp_parser_global_scope_opt (parser,
|
= (cp_parser_global_scope_opt (parser,
|
||||||
/*current_scope_valid_p=*/false)
|
/*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false)
|
||||||
!= NULL_TREE);
|
!= NULL_TREE);
|
||||||
/* Look for the `delete' keyword. */
|
/* Look for the `delete' keyword. */
|
||||||
cp_parser_require_keyword (parser, RID_DELETE, "`delete'");
|
cp_parser_require_keyword (parser, RID_DELETE, "`delete'");
|
||||||
@ -8022,7 +8068,8 @@ cp_parser_mem_initializer_id (cp_parser* parser)
|
|||||||
/* Look for the optional `::' operator. */
|
/* Look for the optional `::' operator. */
|
||||||
global_scope_p
|
global_scope_p
|
||||||
= (cp_parser_global_scope_opt (parser,
|
= (cp_parser_global_scope_opt (parser,
|
||||||
/*current_scope_valid_p=*/false)
|
/*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false)
|
||||||
!= NULL_TREE);
|
!= NULL_TREE);
|
||||||
/* Look for the optional nested-name-specifier. The simplest way to
|
/* Look for the optional nested-name-specifier. The simplest way to
|
||||||
implement:
|
implement:
|
||||||
@ -8594,7 +8641,8 @@ cp_parser_type_parameter (cp_parser* parser)
|
|||||||
/*check_dependency_p=*/true,
|
/*check_dependency_p=*/true,
|
||||||
/*template_p=*/&is_template,
|
/*template_p=*/&is_template,
|
||||||
/*declarator_p=*/false,
|
/*declarator_p=*/false,
|
||||||
/*optional_p=*/false);
|
/*optional_p=*/false,
|
||||||
|
/*member_p=*/false);
|
||||||
if (TREE_CODE (default_argument) == TYPE_DECL)
|
if (TREE_CODE (default_argument) == TYPE_DECL)
|
||||||
/* If the id-expression was a template-id that refers to
|
/* If the id-expression was a template-id that refers to
|
||||||
a template-class, we already have the declaration here,
|
a template-class, we already have the declaration here,
|
||||||
@ -9159,7 +9207,8 @@ cp_parser_template_argument (cp_parser* parser)
|
|||||||
/*check_dependency_p=*/true,
|
/*check_dependency_p=*/true,
|
||||||
&template_p,
|
&template_p,
|
||||||
/*declarator_p=*/false,
|
/*declarator_p=*/false,
|
||||||
/*optional_p=*/false);
|
/*optional_p=*/false,
|
||||||
|
/*member_p=*/false);
|
||||||
/* If the next token isn't a `,' or a `>', then this argument wasn't
|
/* If the next token isn't a `,' or a `>', then this argument wasn't
|
||||||
really finished. */
|
really finished. */
|
||||||
if (!cp_parser_next_token_ends_template_argument_p (parser))
|
if (!cp_parser_next_token_ends_template_argument_p (parser))
|
||||||
@ -9799,7 +9848,8 @@ cp_parser_simple_type_specifier (cp_parser* parser,
|
|||||||
/* Look for the optional `::' operator. */
|
/* Look for the optional `::' operator. */
|
||||||
global_p
|
global_p
|
||||||
= (cp_parser_global_scope_opt (parser,
|
= (cp_parser_global_scope_opt (parser,
|
||||||
/*current_scope_valid_p=*/false)
|
/*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false)
|
||||||
!= NULL_TREE);
|
!= NULL_TREE);
|
||||||
/* Look for the nested-name specifier. */
|
/* Look for the nested-name specifier. */
|
||||||
qualified_p
|
qualified_p
|
||||||
@ -10024,7 +10074,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
|
|||||||
|
|
||||||
/* Look for the `::' operator. */
|
/* Look for the `::' operator. */
|
||||||
cp_parser_global_scope_opt (parser,
|
cp_parser_global_scope_opt (parser,
|
||||||
/*current_scope_valid_p=*/false);
|
/*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false);
|
||||||
/* Look for the nested-name-specifier. */
|
/* Look for the nested-name-specifier. */
|
||||||
if (tag_type == typename_type)
|
if (tag_type == typename_type)
|
||||||
{
|
{
|
||||||
@ -10559,7 +10610,8 @@ cp_parser_qualified_namespace_specifier (cp_parser* parser)
|
|||||||
{
|
{
|
||||||
/* Look for the optional `::'. */
|
/* Look for the optional `::'. */
|
||||||
cp_parser_global_scope_opt (parser,
|
cp_parser_global_scope_opt (parser,
|
||||||
/*current_scope_valid_p=*/false);
|
/*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false);
|
||||||
|
|
||||||
/* Look for the optional nested-name-specifier. */
|
/* Look for the optional nested-name-specifier. */
|
||||||
cp_parser_nested_name_specifier_opt (parser,
|
cp_parser_nested_name_specifier_opt (parser,
|
||||||
@ -10604,7 +10656,8 @@ cp_parser_using_declaration (cp_parser* parser)
|
|||||||
/* Look for the optional global scope qualification. */
|
/* Look for the optional global scope qualification. */
|
||||||
global_scope_p
|
global_scope_p
|
||||||
= (cp_parser_global_scope_opt (parser,
|
= (cp_parser_global_scope_opt (parser,
|
||||||
/*current_scope_valid_p=*/false)
|
/*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false)
|
||||||
!= NULL_TREE);
|
!= NULL_TREE);
|
||||||
|
|
||||||
/* If we saw `typename', or didn't see `::', then there must be a
|
/* If we saw `typename', or didn't see `::', then there must be a
|
||||||
@ -10630,7 +10683,8 @@ cp_parser_using_declaration (cp_parser* parser)
|
|||||||
/*template_keyword_p=*/false,
|
/*template_keyword_p=*/false,
|
||||||
/*check_dependency_p=*/true,
|
/*check_dependency_p=*/true,
|
||||||
/*declarator_p=*/true,
|
/*declarator_p=*/true,
|
||||||
/*optional_p=*/false);
|
/*optional_p=*/false,
|
||||||
|
/*member_p=*/false);
|
||||||
|
|
||||||
/* The function we call to handle a using-declaration is different
|
/* The function we call to handle a using-declaration is different
|
||||||
depending on what scope we are in. */
|
depending on what scope we are in. */
|
||||||
@ -10684,7 +10738,8 @@ cp_parser_using_directive (cp_parser* parser)
|
|||||||
/* And the `namespace' keyword. */
|
/* And the `namespace' keyword. */
|
||||||
cp_parser_require_keyword (parser, RID_NAMESPACE, "`namespace'");
|
cp_parser_require_keyword (parser, RID_NAMESPACE, "`namespace'");
|
||||||
/* Look for the optional `::' operator. */
|
/* Look for the optional `::' operator. */
|
||||||
cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
|
cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false);
|
||||||
/* And the optional nested-name-specifier. */
|
/* And the optional nested-name-specifier. */
|
||||||
cp_parser_nested_name_specifier_opt (parser,
|
cp_parser_nested_name_specifier_opt (parser,
|
||||||
/*typename_keyword_p=*/false,
|
/*typename_keyword_p=*/false,
|
||||||
@ -11752,7 +11807,8 @@ cp_parser_ptr_operator (cp_parser* parser,
|
|||||||
cp_parser_parse_tentatively (parser);
|
cp_parser_parse_tentatively (parser);
|
||||||
/* Look for the optional `::' operator. */
|
/* Look for the optional `::' operator. */
|
||||||
cp_parser_global_scope_opt (parser,
|
cp_parser_global_scope_opt (parser,
|
||||||
/*current_scope_valid_p=*/false);
|
/*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false);
|
||||||
/* Look for the nested-name specifier. */
|
/* Look for the nested-name specifier. */
|
||||||
cp_parser_nested_name_specifier (parser,
|
cp_parser_nested_name_specifier (parser,
|
||||||
/*typename_keyword_p=*/false,
|
/*typename_keyword_p=*/false,
|
||||||
@ -11892,7 +11948,8 @@ cp_parser_declarator_id (cp_parser* parser, bool optional_p)
|
|||||||
/*check_dependency_p=*/false,
|
/*check_dependency_p=*/false,
|
||||||
/*template_p=*/NULL,
|
/*template_p=*/NULL,
|
||||||
/*declarator_p=*/true,
|
/*declarator_p=*/true,
|
||||||
optional_p);
|
optional_p,
|
||||||
|
/*member_p=*/false);
|
||||||
if (id && BASELINK_P (id))
|
if (id && BASELINK_P (id))
|
||||||
id = BASELINK_FUNCTIONS (id);
|
id = BASELINK_FUNCTIONS (id);
|
||||||
return id;
|
return id;
|
||||||
@ -13097,7 +13154,8 @@ cp_parser_class_head (cp_parser* parser,
|
|||||||
issuing an error about it later if this really is a
|
issuing an error about it later if this really is a
|
||||||
class-head. If it turns out just to be an elaborated type
|
class-head. If it turns out just to be an elaborated type
|
||||||
specifier, remain silent. */
|
specifier, remain silent. */
|
||||||
if (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false))
|
if (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false))
|
||||||
qualified_p = true;
|
qualified_p = true;
|
||||||
|
|
||||||
push_deferring_access_checks (dk_no_check);
|
push_deferring_access_checks (dk_no_check);
|
||||||
@ -14083,7 +14141,8 @@ cp_parser_base_specifier (cp_parser* parser)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Look for the optional `::' operator. */
|
/* Look for the optional `::' operator. */
|
||||||
cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
|
cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false);
|
||||||
/* Look for the nested-name-specifier. The simplest way to
|
/* Look for the nested-name-specifier. The simplest way to
|
||||||
implement:
|
implement:
|
||||||
|
|
||||||
@ -15132,7 +15191,8 @@ cp_parser_check_template_parameters (cp_parser* parser,
|
|||||||
present, and NULL_TREE otherwise. */
|
present, and NULL_TREE otherwise. */
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
cp_parser_global_scope_opt (cp_parser* parser, bool current_scope_valid_p)
|
cp_parser_global_scope_opt (cp_parser* parser, bool current_scope_valid_p,
|
||||||
|
bool object_scope_valid_p)
|
||||||
{
|
{
|
||||||
cp_token *token;
|
cp_token *token;
|
||||||
|
|
||||||
@ -15151,12 +15211,15 @@ cp_parser_global_scope_opt (cp_parser* parser, bool current_scope_valid_p)
|
|||||||
|
|
||||||
return parser->scope;
|
return parser->scope;
|
||||||
}
|
}
|
||||||
else if (!current_scope_valid_p)
|
|
||||||
|
if (!current_scope_valid_p)
|
||||||
{
|
{
|
||||||
parser->scope = NULL_TREE;
|
parser->scope = NULL_TREE;
|
||||||
parser->qualifying_scope = NULL_TREE;
|
parser->qualifying_scope = NULL_TREE;
|
||||||
parser->object_scope = NULL_TREE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!object_scope_valid_p)
|
||||||
|
parser->object_scope = NULL_TREE;
|
||||||
|
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
}
|
}
|
||||||
@ -15194,7 +15257,8 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
|
|||||||
|
|
||||||
/* Look for the optional `::' operator. */
|
/* Look for the optional `::' operator. */
|
||||||
cp_parser_global_scope_opt (parser,
|
cp_parser_global_scope_opt (parser,
|
||||||
/*current_scope_valid_p=*/false);
|
/*current_scope_valid_p=*/false,
|
||||||
|
/*object_scope_valid_p=*/false);
|
||||||
/* Look for the nested-name-specifier. */
|
/* Look for the nested-name-specifier. */
|
||||||
nested_name_p
|
nested_name_p
|
||||||
= (cp_parser_nested_name_specifier_opt (parser,
|
= (cp_parser_nested_name_specifier_opt (parser,
|
||||||
@ -17901,7 +17965,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
|
|||||||
/*check_dependency_p=*/true,
|
/*check_dependency_p=*/true,
|
||||||
/*template_p=*/NULL,
|
/*template_p=*/NULL,
|
||||||
/*declarator_p=*/false,
|
/*declarator_p=*/false,
|
||||||
/*optional_p=*/false);
|
/*optional_p=*/false,
|
||||||
|
/*member_p=*/false);
|
||||||
if (name == error_mark_node)
|
if (name == error_mark_node)
|
||||||
goto skip_comma;
|
goto skip_comma;
|
||||||
|
|
||||||
|
@ -9200,6 +9200,14 @@ tsubst_copy_and_build (tree t,
|
|||||||
member = tsubst_baselink (member,
|
member = tsubst_baselink (member,
|
||||||
non_reference (TREE_TYPE (object)),
|
non_reference (TREE_TYPE (object)),
|
||||||
args, complain, in_decl);
|
args, complain, in_decl);
|
||||||
|
else if (TREE_CODE (member) == BIT_NOT_EXPR
|
||||||
|
&& !TYPE_P (TREE_OPERAND (member, 0)))
|
||||||
|
{
|
||||||
|
tree id = TREE_OPERAND (member, 0);
|
||||||
|
id = make_typename_type (object_type, id, typename_type, complain);
|
||||||
|
gcc_assert (TREE_CODE (id) != TYPENAME_TYPE);
|
||||||
|
member = build_nt (BIT_NOT_EXPR, id);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
member = tsubst_copy (member, args, complain, in_decl);
|
member = tsubst_copy (member, args, complain, in_decl);
|
||||||
if (member == error_mark_node)
|
if (member == error_mark_node)
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2006-09-01 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
PR c++/23287
|
||||||
|
* g++.dg/parse/dtor12.C: New.
|
||||||
|
|
||||||
2006-08-31 Zdenek Dvorak <dvorakz@suse.cz>
|
2006-08-31 Zdenek Dvorak <dvorakz@suse.cz>
|
||||||
|
|
||||||
PR tree-optimization/28839
|
PR tree-optimization/28839
|
||||||
|
15
gcc/testsuite/g++.dg/parse/dtor12.C
Normal file
15
gcc/testsuite/g++.dg/parse/dtor12.C
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (C) 2006 Free Software Foundation, Inc.
|
||||||
|
// Contributed by Nathan Sidwell 1 Sep 2006 <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
// PR 23287: Failure to parse dependent dtor name
|
||||||
|
// Origin:Wolfgang Bangerth <bangerth@dealii.org>
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> struct A {};
|
||||||
|
|
||||||
|
template <class T> void f(A<T> *ptr) {
|
||||||
|
ptr->~A();
|
||||||
|
}
|
||||||
|
|
||||||
|
template void f<void> (A<void> *);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user