mirror of git://gcc.gnu.org/git/gcc.git
PR c++/88548 - this accepted in static member functions.
* parser.c (cp_debug_parser): Adjust printing of local_variables_forbidden_p. (cp_parser_new): Set local_variables_forbidden_p to 0 rather than false. (cp_parser_primary_expression): When checking local_variables_forbidden_p, use THIS_FORBIDDEN or LOCAL_VARS_FORBIDDEN. (cp_parser_lambda_body): Update the type of local_variables_forbidden_p. Set it to 0 rather than false. (cp_parser_condition): Adjust call to cp_parser_declarator. (cp_parser_explicit_instantiation): Likewise. (cp_parser_init_declarator): Likewise. (cp_parser_declarator): New parameter. Use it. (cp_parser_direct_declarator): New parameter. Use it to set local_variables_forbidden_p. Adjust call to cp_parser_declarator. (cp_parser_type_id_1): Adjust call to cp_parser_declarator. (cp_parser_parameter_declaration): Likewise. (cp_parser_default_argument): Update the type of local_variables_forbidden_p. Set it to LOCAL_VARS_AND_THIS_FORBIDDEN rather than true. (cp_parser_member_declaration): Tell cp_parser_declarator if we saw 'static' or 'friend'. (cp_parser_exception_declaration): Adjust call to cp_parser_declarator. (cp_parser_late_parsing_default_args): Update the type of local_variables_forbidden_p. Set it to LOCAL_VARS_AND_THIS_FORBIDDEN rather than true. (cp_parser_cache_defarg): Adjust call to cp_parser_declarator. (cp_parser_objc_class_ivars): Likewise. (cp_parser_objc_struct_declaration): Likewise. (cp_parser_omp_for_loop_init): Likewise. * parser.h (cp_parser): Change the type of local_variables_forbidden_p to unsigned char. (LOCAL_VARS_FORBIDDEN, LOCAL_VARS_AND_THIS_FORBIDDEN, THIS_FORBIDDEN): Define. * g++.dg/cpp0x/this1.C: New test. From-SVN: r267731
This commit is contained in:
parent
5a5474ba24
commit
e01ffb47c6
|
|
@ -1,3 +1,40 @@
|
||||||
|
2019-01-08 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
|
PR c++/88548 - this accepted in static member functions.
|
||||||
|
* parser.c (cp_debug_parser): Adjust printing of
|
||||||
|
local_variables_forbidden_p.
|
||||||
|
(cp_parser_new): Set local_variables_forbidden_p to 0 rather than false.
|
||||||
|
(cp_parser_primary_expression): When checking
|
||||||
|
local_variables_forbidden_p, use THIS_FORBIDDEN or
|
||||||
|
LOCAL_VARS_FORBIDDEN.
|
||||||
|
(cp_parser_lambda_body): Update the type of
|
||||||
|
local_variables_forbidden_p. Set it to 0 rather than false.
|
||||||
|
(cp_parser_condition): Adjust call to cp_parser_declarator.
|
||||||
|
(cp_parser_explicit_instantiation): Likewise.
|
||||||
|
(cp_parser_init_declarator): Likewise.
|
||||||
|
(cp_parser_declarator): New parameter. Use it.
|
||||||
|
(cp_parser_direct_declarator): New parameter. Use it to set
|
||||||
|
local_variables_forbidden_p. Adjust call to cp_parser_declarator.
|
||||||
|
(cp_parser_type_id_1): Adjust call to cp_parser_declarator.
|
||||||
|
(cp_parser_parameter_declaration): Likewise.
|
||||||
|
(cp_parser_default_argument): Update the type of
|
||||||
|
local_variables_forbidden_p. Set it to LOCAL_VARS_AND_THIS_FORBIDDEN
|
||||||
|
rather than true.
|
||||||
|
(cp_parser_member_declaration): Tell cp_parser_declarator if we saw
|
||||||
|
'static' or 'friend'.
|
||||||
|
(cp_parser_exception_declaration): Adjust call to cp_parser_declarator.
|
||||||
|
(cp_parser_late_parsing_default_args): Update the type of
|
||||||
|
local_variables_forbidden_p. Set it to LOCAL_VARS_AND_THIS_FORBIDDEN
|
||||||
|
rather than true.
|
||||||
|
(cp_parser_cache_defarg): Adjust call to cp_parser_declarator.
|
||||||
|
(cp_parser_objc_class_ivars): Likewise.
|
||||||
|
(cp_parser_objc_struct_declaration): Likewise.
|
||||||
|
(cp_parser_omp_for_loop_init): Likewise.
|
||||||
|
* parser.h (cp_parser): Change the type of local_variables_forbidden_p
|
||||||
|
to unsigned char.
|
||||||
|
(LOCAL_VARS_FORBIDDEN, LOCAL_VARS_AND_THIS_FORBIDDEN, THIS_FORBIDDEN):
|
||||||
|
Define.
|
||||||
|
|
||||||
2019-01-08 Paolo Carlini <paolo.carlini@oracle.com>
|
2019-01-08 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
* decl.c (start_decl): Improve permerror location.
|
* decl.c (start_decl): Improve permerror location.
|
||||||
|
|
|
||||||
|
|
@ -536,9 +536,12 @@ cp_debug_parser (FILE *file, cp_parser *parser)
|
||||||
parser->allow_non_integral_constant_expression_p);
|
parser->allow_non_integral_constant_expression_p);
|
||||||
cp_debug_print_flag (file, "Seen non-constant expression",
|
cp_debug_print_flag (file, "Seen non-constant expression",
|
||||||
parser->non_integral_constant_expression_p);
|
parser->non_integral_constant_expression_p);
|
||||||
cp_debug_print_flag (file, "Local names and 'this' forbidden in "
|
cp_debug_print_flag (file, "Local names forbidden in current context",
|
||||||
"current context",
|
(parser->local_variables_forbidden_p
|
||||||
parser->local_variables_forbidden_p);
|
& LOCAL_VARS_FORBIDDEN));
|
||||||
|
cp_debug_print_flag (file, "'this' forbidden in current context",
|
||||||
|
(parser->local_variables_forbidden_p
|
||||||
|
& THIS_FORBIDDEN));
|
||||||
cp_debug_print_flag (file, "In unbraced linkage specification",
|
cp_debug_print_flag (file, "In unbraced linkage specification",
|
||||||
parser->in_unbraced_linkage_specification_p);
|
parser->in_unbraced_linkage_specification_p);
|
||||||
cp_debug_print_flag (file, "Parsing a declarator",
|
cp_debug_print_flag (file, "Parsing a declarator",
|
||||||
|
|
@ -2203,9 +2206,10 @@ static tree cp_parser_init_declarator
|
||||||
location_t *, tree *);
|
location_t *, tree *);
|
||||||
static cp_declarator *cp_parser_declarator
|
static cp_declarator *cp_parser_declarator
|
||||||
(cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool *,
|
(cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool *,
|
||||||
bool, bool);
|
bool, bool, bool);
|
||||||
static cp_declarator *cp_parser_direct_declarator
|
static cp_declarator *cp_parser_direct_declarator
|
||||||
(cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool, bool);
|
(cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool, bool,
|
||||||
|
bool);
|
||||||
static enum tree_code cp_parser_ptr_operator
|
static enum tree_code cp_parser_ptr_operator
|
||||||
(cp_parser *, tree *, cp_cv_quals *, tree *);
|
(cp_parser *, tree *, cp_cv_quals *, tree *);
|
||||||
static cp_cv_quals cp_parser_cv_qualifier_seq_opt
|
static cp_cv_quals cp_parser_cv_qualifier_seq_opt
|
||||||
|
|
@ -3951,7 +3955,7 @@ cp_parser_new (void)
|
||||||
parser->non_integral_constant_expression_p = false;
|
parser->non_integral_constant_expression_p = false;
|
||||||
|
|
||||||
/* Local variable names are not forbidden. */
|
/* Local variable names are not forbidden. */
|
||||||
parser->local_variables_forbidden_p = false;
|
parser->local_variables_forbidden_p = 0;
|
||||||
|
|
||||||
/* We are not processing an `extern "C"' declaration. */
|
/* We are not processing an `extern "C"' declaration. */
|
||||||
parser->in_unbraced_linkage_specification_p = false;
|
parser->in_unbraced_linkage_specification_p = false;
|
||||||
|
|
@ -5405,7 +5409,7 @@ cp_parser_primary_expression (cp_parser *parser,
|
||||||
/* Recognize the `this' keyword. */
|
/* Recognize the `this' keyword. */
|
||||||
case RID_THIS:
|
case RID_THIS:
|
||||||
cp_lexer_consume_token (parser->lexer);
|
cp_lexer_consume_token (parser->lexer);
|
||||||
if (parser->local_variables_forbidden_p)
|
if (parser->local_variables_forbidden_p & THIS_FORBIDDEN)
|
||||||
{
|
{
|
||||||
error_at (token->location,
|
error_at (token->location,
|
||||||
"%<this%> may not be used in this context");
|
"%<this%> may not be used in this context");
|
||||||
|
|
@ -5688,7 +5692,7 @@ cp_parser_primary_expression (cp_parser *parser,
|
||||||
}
|
}
|
||||||
/* Check to see if DECL is a local variable in a context
|
/* Check to see if DECL is a local variable in a context
|
||||||
where that is forbidden. */
|
where that is forbidden. */
|
||||||
if (parser->local_variables_forbidden_p
|
if ((parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
|
||||||
&& local_variable_p (decl))
|
&& local_variable_p (decl))
|
||||||
{
|
{
|
||||||
error_at (id_expression.get_location (),
|
error_at (id_expression.get_location (),
|
||||||
|
|
@ -10928,7 +10932,8 @@ static void
|
||||||
cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
|
cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
|
||||||
{
|
{
|
||||||
bool nested = (current_function_decl != NULL_TREE);
|
bool nested = (current_function_decl != NULL_TREE);
|
||||||
bool local_variables_forbidden_p = parser->local_variables_forbidden_p;
|
unsigned char local_variables_forbidden_p
|
||||||
|
= parser->local_variables_forbidden_p;
|
||||||
bool in_function_body = parser->in_function_body;
|
bool in_function_body = parser->in_function_body;
|
||||||
|
|
||||||
/* The body of a lambda-expression is not a subexpression of the enclosing
|
/* The body of a lambda-expression is not a subexpression of the enclosing
|
||||||
|
|
@ -10945,7 +10950,7 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
|
||||||
vec<tree> omp_privatization_save;
|
vec<tree> omp_privatization_save;
|
||||||
save_omp_privatization_clauses (omp_privatization_save);
|
save_omp_privatization_clauses (omp_privatization_save);
|
||||||
/* Clear this in case we're in the middle of a default argument. */
|
/* Clear this in case we're in the middle of a default argument. */
|
||||||
parser->local_variables_forbidden_p = false;
|
parser->local_variables_forbidden_p = 0;
|
||||||
parser->in_function_body = true;
|
parser->in_function_body = true;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -11990,7 +11995,8 @@ cp_parser_condition (cp_parser* parser)
|
||||||
/*ctor_dtor_or_conv_p=*/NULL,
|
/*ctor_dtor_or_conv_p=*/NULL,
|
||||||
/*parenthesized_p=*/NULL,
|
/*parenthesized_p=*/NULL,
|
||||||
/*member_p=*/false,
|
/*member_p=*/false,
|
||||||
/*friend_p=*/false);
|
/*friend_p=*/false,
|
||||||
|
/*static_p=*/false);
|
||||||
/* Parse the attributes. */
|
/* Parse the attributes. */
|
||||||
attributes = cp_parser_attributes_opt (parser);
|
attributes = cp_parser_attributes_opt (parser);
|
||||||
/* Parse the asm-specification. */
|
/* Parse the asm-specification. */
|
||||||
|
|
@ -17123,7 +17129,8 @@ cp_parser_explicit_instantiation (cp_parser* parser)
|
||||||
/*ctor_dtor_or_conv_p=*/NULL,
|
/*ctor_dtor_or_conv_p=*/NULL,
|
||||||
/*parenthesized_p=*/NULL,
|
/*parenthesized_p=*/NULL,
|
||||||
/*member_p=*/false,
|
/*member_p=*/false,
|
||||||
/*friend_p=*/false);
|
/*friend_p=*/false,
|
||||||
|
/*static_p=*/false);
|
||||||
if (declares_class_or_enum & 2)
|
if (declares_class_or_enum & 2)
|
||||||
cp_parser_check_for_definition_in_return_type (declarator,
|
cp_parser_check_for_definition_in_return_type (declarator,
|
||||||
decl_specifiers.type,
|
decl_specifiers.type,
|
||||||
|
|
@ -20068,7 +20075,7 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||||
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||||
flags, &ctor_dtor_or_conv_p,
|
flags, &ctor_dtor_or_conv_p,
|
||||||
/*parenthesized_p=*/NULL,
|
/*parenthesized_p=*/NULL,
|
||||||
member_p, friend_p);
|
member_p, friend_p, /*static_p=*/false);
|
||||||
/* Gather up the deferred checks. */
|
/* Gather up the deferred checks. */
|
||||||
stop_deferring_access_checks ();
|
stop_deferring_access_checks ();
|
||||||
|
|
||||||
|
|
@ -20486,7 +20493,9 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||||
|
|
||||||
MEMBER_P is true iff this declarator is a member-declarator.
|
MEMBER_P is true iff this declarator is a member-declarator.
|
||||||
|
|
||||||
FRIEND_P is true iff this declarator is a friend. */
|
FRIEND_P is true iff this declarator is a friend.
|
||||||
|
|
||||||
|
STATIC_P is true iff the keyword static was seen. */
|
||||||
|
|
||||||
static cp_declarator *
|
static cp_declarator *
|
||||||
cp_parser_declarator (cp_parser* parser,
|
cp_parser_declarator (cp_parser* parser,
|
||||||
|
|
@ -20494,7 +20503,7 @@ cp_parser_declarator (cp_parser* parser,
|
||||||
cp_parser_flags flags,
|
cp_parser_flags flags,
|
||||||
int* ctor_dtor_or_conv_p,
|
int* ctor_dtor_or_conv_p,
|
||||||
bool* parenthesized_p,
|
bool* parenthesized_p,
|
||||||
bool member_p, bool friend_p)
|
bool member_p, bool friend_p, bool static_p)
|
||||||
{
|
{
|
||||||
cp_declarator *declarator;
|
cp_declarator *declarator;
|
||||||
enum tree_code code;
|
enum tree_code code;
|
||||||
|
|
@ -20536,7 +20545,7 @@ cp_parser_declarator (cp_parser* parser,
|
||||||
/*ctor_dtor_or_conv_p=*/NULL,
|
/*ctor_dtor_or_conv_p=*/NULL,
|
||||||
/*parenthesized_p=*/NULL,
|
/*parenthesized_p=*/NULL,
|
||||||
/*member_p=*/false,
|
/*member_p=*/false,
|
||||||
friend_p);
|
friend_p, /*static_p=*/false);
|
||||||
|
|
||||||
/* If we are parsing an abstract-declarator, we must handle the
|
/* If we are parsing an abstract-declarator, we must handle the
|
||||||
case where the dependent declarator is absent. */
|
case where the dependent declarator is absent. */
|
||||||
|
|
@ -20555,7 +20564,7 @@ cp_parser_declarator (cp_parser* parser,
|
||||||
CPP_OPEN_PAREN);
|
CPP_OPEN_PAREN);
|
||||||
declarator = cp_parser_direct_declarator (parser, dcl_kind,
|
declarator = cp_parser_direct_declarator (parser, dcl_kind,
|
||||||
flags, ctor_dtor_or_conv_p,
|
flags, ctor_dtor_or_conv_p,
|
||||||
member_p, friend_p);
|
member_p, friend_p, static_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gnu_attributes && declarator && declarator != cp_error_declarator)
|
if (gnu_attributes && declarator && declarator != cp_error_declarator)
|
||||||
|
|
@ -20591,7 +20600,7 @@ cp_parser_declarator (cp_parser* parser,
|
||||||
of ambiguity we prefer an abstract declarator, as per
|
of ambiguity we prefer an abstract declarator, as per
|
||||||
[dcl.ambig.res].
|
[dcl.ambig.res].
|
||||||
The parser flags FLAGS is used to control type-specifier parsing.
|
The parser flags FLAGS is used to control type-specifier parsing.
|
||||||
CTOR_DTOR_OR_CONV_P, MEMBER_P, and FRIEND_P are
|
CTOR_DTOR_OR_CONV_P, MEMBER_P, FRIEND_P, and STATIC_P are
|
||||||
as for cp_parser_declarator. */
|
as for cp_parser_declarator. */
|
||||||
|
|
||||||
static cp_declarator *
|
static cp_declarator *
|
||||||
|
|
@ -20599,7 +20608,7 @@ cp_parser_direct_declarator (cp_parser* parser,
|
||||||
cp_parser_declarator_kind dcl_kind,
|
cp_parser_declarator_kind dcl_kind,
|
||||||
cp_parser_flags flags,
|
cp_parser_flags flags,
|
||||||
int* ctor_dtor_or_conv_p,
|
int* ctor_dtor_or_conv_p,
|
||||||
bool member_p, bool friend_p)
|
bool member_p, bool friend_p, bool static_p)
|
||||||
{
|
{
|
||||||
cp_token *token;
|
cp_token *token;
|
||||||
cp_declarator *declarator = NULL;
|
cp_declarator *declarator = NULL;
|
||||||
|
|
@ -20702,6 +20711,11 @@ cp_parser_direct_declarator (cp_parser* parser,
|
||||||
tree attrs;
|
tree attrs;
|
||||||
bool memfn = (member_p || (pushed_scope
|
bool memfn = (member_p || (pushed_scope
|
||||||
&& CLASS_TYPE_P (pushed_scope)));
|
&& CLASS_TYPE_P (pushed_scope)));
|
||||||
|
unsigned char local_variables_forbidden_p
|
||||||
|
= parser->local_variables_forbidden_p;
|
||||||
|
/* 'this' is not allowed in static member functions. */
|
||||||
|
if (static_p || friend_p)
|
||||||
|
parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
|
||||||
|
|
||||||
is_declarator = true;
|
is_declarator = true;
|
||||||
|
|
||||||
|
|
@ -20749,6 +20763,10 @@ cp_parser_direct_declarator (cp_parser* parser,
|
||||||
return type, so are not those of the declared
|
return type, so are not those of the declared
|
||||||
function. */
|
function. */
|
||||||
parser->default_arg_ok_p = false;
|
parser->default_arg_ok_p = false;
|
||||||
|
|
||||||
|
/* Restore the state of local_variables_forbidden_p. */
|
||||||
|
parser->local_variables_forbidden_p
|
||||||
|
= local_variables_forbidden_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the function parms from scope. */
|
/* Remove the function parms from scope. */
|
||||||
|
|
@ -20779,7 +20797,8 @@ cp_parser_direct_declarator (cp_parser* parser,
|
||||||
= cp_parser_declarator (parser, dcl_kind, flags,
|
= cp_parser_declarator (parser, dcl_kind, flags,
|
||||||
ctor_dtor_or_conv_p,
|
ctor_dtor_or_conv_p,
|
||||||
/*parenthesized_p=*/NULL,
|
/*parenthesized_p=*/NULL,
|
||||||
member_p, friend_p);
|
member_p, friend_p,
|
||||||
|
/*static_p=*/false);
|
||||||
parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
|
parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
|
||||||
first = false;
|
first = false;
|
||||||
/* Expect a `)'. */
|
/* Expect a `)'. */
|
||||||
|
|
@ -21673,7 +21692,8 @@ cp_parser_type_id_1 (cp_parser *parser, cp_parser_flags flags,
|
||||||
CP_PARSER_FLAGS_NONE, NULL,
|
CP_PARSER_FLAGS_NONE, NULL,
|
||||||
/*parenthesized_p=*/NULL,
|
/*parenthesized_p=*/NULL,
|
||||||
/*member_p=*/false,
|
/*member_p=*/false,
|
||||||
/*friend_p=*/false);
|
/*friend_p=*/false,
|
||||||
|
/*static_p=*/false);
|
||||||
/* Check to see if there really was a declarator. */
|
/* Check to see if there really was a declarator. */
|
||||||
if (!cp_parser_parse_definitely (parser))
|
if (!cp_parser_parse_definitely (parser))
|
||||||
abstract_declarator = NULL;
|
abstract_declarator = NULL;
|
||||||
|
|
@ -22258,7 +22278,8 @@ cp_parser_parameter_declaration (cp_parser *parser,
|
||||||
/*ctor_dtor_or_conv_p=*/NULL,
|
/*ctor_dtor_or_conv_p=*/NULL,
|
||||||
parenthesized_p,
|
parenthesized_p,
|
||||||
/*member_p=*/false,
|
/*member_p=*/false,
|
||||||
/*friend_p=*/false);
|
/*friend_p=*/false,
|
||||||
|
/*static_p=*/false);
|
||||||
parser->default_arg_ok_p = saved_default_arg_ok_p;
|
parser->default_arg_ok_p = saved_default_arg_ok_p;
|
||||||
/* After the declarator, allow more attributes. */
|
/* After the declarator, allow more attributes. */
|
||||||
decl_specifiers.attributes
|
decl_specifiers.attributes
|
||||||
|
|
@ -22439,7 +22460,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
|
||||||
{
|
{
|
||||||
tree default_argument = NULL_TREE;
|
tree default_argument = NULL_TREE;
|
||||||
bool saved_greater_than_is_operator_p;
|
bool saved_greater_than_is_operator_p;
|
||||||
bool saved_local_variables_forbidden_p;
|
unsigned char saved_local_variables_forbidden_p;
|
||||||
bool non_constant_p, is_direct_init;
|
bool non_constant_p, is_direct_init;
|
||||||
|
|
||||||
/* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is
|
/* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is
|
||||||
|
|
@ -22449,7 +22470,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
|
||||||
/* Local variable names (and the `this' keyword) may not
|
/* Local variable names (and the `this' keyword) may not
|
||||||
appear in a default argument. */
|
appear in a default argument. */
|
||||||
saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
|
saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
|
||||||
parser->local_variables_forbidden_p = true;
|
parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;
|
||||||
/* Parse the assignment-expression. */
|
/* Parse the assignment-expression. */
|
||||||
if (template_parm_p)
|
if (template_parm_p)
|
||||||
push_deferring_access_checks (dk_no_deferred);
|
push_deferring_access_checks (dk_no_deferred);
|
||||||
|
|
@ -24468,6 +24489,7 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||||
cp_declarator *declarator;
|
cp_declarator *declarator;
|
||||||
tree asm_specification;
|
tree asm_specification;
|
||||||
int ctor_dtor_or_conv_p;
|
int ctor_dtor_or_conv_p;
|
||||||
|
bool static_p = (decl_specifiers.storage_class == sc_static);
|
||||||
|
|
||||||
/* Parse the declarator. */
|
/* Parse the declarator. */
|
||||||
declarator
|
declarator
|
||||||
|
|
@ -24476,7 +24498,7 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||||
&ctor_dtor_or_conv_p,
|
&ctor_dtor_or_conv_p,
|
||||||
/*parenthesized_p=*/NULL,
|
/*parenthesized_p=*/NULL,
|
||||||
/*member_p=*/true,
|
/*member_p=*/true,
|
||||||
friend_p);
|
friend_p, static_p);
|
||||||
|
|
||||||
/* If something went wrong parsing the declarator, make sure
|
/* If something went wrong parsing the declarator, make sure
|
||||||
that we at least consume some tokens. */
|
that we at least consume some tokens. */
|
||||||
|
|
@ -25357,7 +25379,8 @@ cp_parser_exception_declaration (cp_parser* parser)
|
||||||
/*ctor_dtor_or_conv_p=*/NULL,
|
/*ctor_dtor_or_conv_p=*/NULL,
|
||||||
/*parenthesized_p=*/NULL,
|
/*parenthesized_p=*/NULL,
|
||||||
/*member_p=*/false,
|
/*member_p=*/false,
|
||||||
/*friend_p=*/false);
|
/*friend_p=*/false,
|
||||||
|
/*static_p=*/false);
|
||||||
|
|
||||||
/* Restore the saved message. */
|
/* Restore the saved message. */
|
||||||
parser->type_definition_forbidden_message = saved_message;
|
parser->type_definition_forbidden_message = saved_message;
|
||||||
|
|
@ -28602,7 +28625,7 @@ cp_parser_late_parsing_nsdmi (cp_parser *parser, tree field)
|
||||||
static void
|
static void
|
||||||
cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
|
cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
|
||||||
{
|
{
|
||||||
bool saved_local_variables_forbidden_p;
|
unsigned char saved_local_variables_forbidden_p;
|
||||||
tree parm, parmdecl;
|
tree parm, parmdecl;
|
||||||
|
|
||||||
/* While we're parsing the default args, we might (due to the
|
/* While we're parsing the default args, we might (due to the
|
||||||
|
|
@ -28614,7 +28637,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
|
||||||
/* Local variable names (and the `this' keyword) may not appear
|
/* Local variable names (and the `this' keyword) may not appear
|
||||||
in a default argument. */
|
in a default argument. */
|
||||||
saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
|
saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
|
||||||
parser->local_variables_forbidden_p = true;
|
parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;
|
||||||
|
|
||||||
push_defarg_context (fn);
|
push_defarg_context (fn);
|
||||||
|
|
||||||
|
|
@ -29693,7 +29716,8 @@ cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
|
||||||
&ctor_dtor_or_conv_p,
|
&ctor_dtor_or_conv_p,
|
||||||
/*parenthesized_p=*/NULL,
|
/*parenthesized_p=*/NULL,
|
||||||
/*member_p=*/true,
|
/*member_p=*/true,
|
||||||
/*friend_p=*/false);
|
/*friend_p=*/false,
|
||||||
|
/*static_p=*/false);
|
||||||
peek = cp_lexer_peek_token (parser->lexer);
|
peek = cp_lexer_peek_token (parser->lexer);
|
||||||
if (cp_parser_error_occurred (parser))
|
if (cp_parser_error_occurred (parser))
|
||||||
break;
|
break;
|
||||||
|
|
@ -31060,7 +31084,8 @@ cp_parser_objc_class_ivars (cp_parser* parser)
|
||||||
&ctor_dtor_or_conv_p,
|
&ctor_dtor_or_conv_p,
|
||||||
/*parenthesized_p=*/NULL,
|
/*parenthesized_p=*/NULL,
|
||||||
/*member_p=*/false,
|
/*member_p=*/false,
|
||||||
/*friend_p=*/false);
|
/*friend_p=*/false,
|
||||||
|
/*static_p=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look for attributes that apply to the ivar. */
|
/* Look for attributes that apply to the ivar. */
|
||||||
|
|
@ -31618,7 +31643,7 @@ cp_parser_objc_struct_declaration (cp_parser *parser)
|
||||||
/* Parse the declarator. */
|
/* Parse the declarator. */
|
||||||
declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||||
CP_PARSER_FLAGS_NONE,
|
CP_PARSER_FLAGS_NONE,
|
||||||
NULL, NULL, false, false);
|
NULL, NULL, false, false, false);
|
||||||
|
|
||||||
/* Look for attributes that apply to the ivar. */
|
/* Look for attributes that apply to the ivar. */
|
||||||
attributes = cp_parser_attributes_opt (parser);
|
attributes = cp_parser_attributes_opt (parser);
|
||||||
|
|
@ -36251,7 +36276,8 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
|
||||||
/*ctor_dtor_or_conv_p=*/NULL,
|
/*ctor_dtor_or_conv_p=*/NULL,
|
||||||
/*parenthesized_p=*/NULL,
|
/*parenthesized_p=*/NULL,
|
||||||
/*member_p=*/false,
|
/*member_p=*/false,
|
||||||
/*friend_p=*/false);
|
/*friend_p=*/false,
|
||||||
|
/*static_p=*/false);
|
||||||
attributes = cp_parser_attributes_opt (parser);
|
attributes = cp_parser_attributes_opt (parser);
|
||||||
asm_specification = cp_parser_asm_specification_opt (parser);
|
asm_specification = cp_parser_asm_specification_opt (parser);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -282,9 +282,12 @@ struct GTY(()) cp_parser {
|
||||||
been seen that makes the expression non-constant. */
|
been seen that makes the expression non-constant. */
|
||||||
bool non_integral_constant_expression_p;
|
bool non_integral_constant_expression_p;
|
||||||
|
|
||||||
/* TRUE if local variable names and `this' are forbidden in the
|
/* Used to track if local variable names and/or `this' are forbidden
|
||||||
current context. */
|
in the current context. */
|
||||||
bool local_variables_forbidden_p;
|
#define LOCAL_VARS_FORBIDDEN (1 << 0)
|
||||||
|
#define THIS_FORBIDDEN (1 << 1)
|
||||||
|
#define LOCAL_VARS_AND_THIS_FORBIDDEN (LOCAL_VARS_FORBIDDEN | THIS_FORBIDDEN)
|
||||||
|
unsigned char local_variables_forbidden_p;
|
||||||
|
|
||||||
/* TRUE if the declaration we are parsing is part of a
|
/* TRUE if the declaration we are parsing is part of a
|
||||||
linkage-specification of the form `extern string-literal
|
linkage-specification of the form `extern string-literal
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2019-01-08 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
|
PR c++/88548 - this accepted in static member functions.
|
||||||
|
* g++.dg/cpp0x/this1.C: New test.
|
||||||
|
|
||||||
2019-01-08 Martin Liska <mliska@suse.cz>
|
2019-01-08 Martin Liska <mliska@suse.cz>
|
||||||
|
|
||||||
PR tree-optimization/88753
|
PR tree-optimization/88753
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
// PR c++/88548
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
|
||||||
|
struct S1 {
|
||||||
|
int a;
|
||||||
|
auto m1 () -> decltype(this->a) { return 0; }
|
||||||
|
auto m2 () -> decltype(this) { return 0; }
|
||||||
|
void m3 () noexcept(noexcept(this->a)) { }
|
||||||
|
void m4 () noexcept(noexcept(this)) { }
|
||||||
|
|
||||||
|
static auto m5 () -> decltype(this->a) { return 0; } // { dg-error ".this. may not be used in this context" }
|
||||||
|
static auto m6 () -> decltype(this) { return 0; } // { dg-error ".this. may not be used in this context" }
|
||||||
|
static void m7 () noexcept(noexcept(this->a)) { } // { dg-error ".this. may not be used in this context" }
|
||||||
|
static void m8 () noexcept(noexcept(this)) { } // { dg-error ".this. may not be used in this context" }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct S2 {
|
||||||
|
static auto f1(T arg) -> decltype((arg));
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S3 {
|
||||||
|
int a;
|
||||||
|
void f1 () noexcept(noexcept(a)) { }
|
||||||
|
static void f2() noexcept(noexcept(a)) { }
|
||||||
|
static auto f3() -> decltype(a);
|
||||||
|
static auto f4() -> decltype((a));
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class S4 {
|
||||||
|
T i;
|
||||||
|
friend int foo(const S4 &t) noexcept(noexcept(i)) { return t.i; }
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
test ()
|
||||||
|
{
|
||||||
|
S4<int> t;
|
||||||
|
foo(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S5 {
|
||||||
|
friend auto bar() -> decltype(this); // { dg-error ".this. may not be used in this context" }
|
||||||
|
auto bar2() -> decltype(this);
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue