re PR c++/19200 (Friend declaration misinterpreted as constructor)
/cp 2014-06-11 Paolo Carlini <paolo.carlini@oracle.com> PR c++/19200 * parser.c (cp_parser_declarator): Add bool parameter. (cp_parser_direct_declarator): Likewise, use it. (cp_parser_member_declaration): Pass friend_p to cp_parser_declarator. (cp_parser_condition, cp_parser_explicit_instantiation, cp_parser_init_declarator, cp_parser_type_id_1, cp_parser_parameter_declaration, cp_parser_exception_declaration, cp_parser_cache_defarg, cp_parser_objc_class_ivars, cp_parser_objc_struct_declaration, cp_parser_omp_for_loop_init): Adjust. * decl.c (grokdeclarator): Fix handling of friend declared in namespace scope (g++.dg/parse/friend10.C). /testsuite 2014-06-11 Paolo Carlini <paolo.carlini@oracle.com> PR c++/19200 * g++.dg/parse/friend9.C: New. * g++.dg/parse/friend10.C: Likewise. * g++.dg/parse/friend7.C: Adjust. From-SVN: r211467
This commit is contained in:
parent
f8c59c0509
commit
d0ba67dc04
@ -1,6 +1,22 @@
|
||||
2014-06-11 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/19200
|
||||
* parser.c (cp_parser_declarator): Add bool parameter.
|
||||
(cp_parser_direct_declarator): Likewise, use it.
|
||||
(cp_parser_member_declaration): Pass friend_p to cp_parser_declarator.
|
||||
(cp_parser_condition, cp_parser_explicit_instantiation,
|
||||
cp_parser_init_declarator, cp_parser_type_id_1,
|
||||
cp_parser_parameter_declaration, cp_parser_exception_declaration,
|
||||
cp_parser_cache_defarg, cp_parser_objc_class_ivars,
|
||||
cp_parser_objc_struct_declaration, cp_parser_omp_for_loop_init):
|
||||
Adjust.
|
||||
* decl.c (grokdeclarator): Fix handling of friend declared in
|
||||
namespace scope (g++.dg/parse/friend10.C).
|
||||
|
||||
2014-06-10 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
* vtable-class-hierarchy.c: Use symtab_get_node (var_decl)->implicit_section.
|
||||
* vtable-class-hierarchy.c: Use symtab_get_node (var_decl)
|
||||
->implicit_section.
|
||||
* optimize.c (cdtor_comdat_group): Fix handling of aliases.
|
||||
(maybe_clone_body): Move symbol across comdat groups.
|
||||
* method.c (use_thunk): Copy implicit section flag.
|
||||
|
@ -9686,7 +9686,7 @@ grokdeclarator (const cp_declarator *declarator,
|
||||
if (ctype == NULL_TREE
|
||||
&& decl_context == FIELD
|
||||
&& funcdecl_p
|
||||
&& (friendp == 0 || dname == current_class_name))
|
||||
&& friendp == 0)
|
||||
ctype = current_class_type;
|
||||
|
||||
if (ctype && (sfk == sfk_constructor
|
||||
|
@ -2078,9 +2078,9 @@ static tree cp_parser_decltype
|
||||
static tree cp_parser_init_declarator
|
||||
(cp_parser *, cp_decl_specifier_seq *, vec<deferred_access_check, va_gc> *, bool, bool, int, bool *, tree *);
|
||||
static cp_declarator *cp_parser_declarator
|
||||
(cp_parser *, cp_parser_declarator_kind, int *, bool *, bool);
|
||||
(cp_parser *, cp_parser_declarator_kind, int *, bool *, bool, bool);
|
||||
static cp_declarator *cp_parser_direct_declarator
|
||||
(cp_parser *, cp_parser_declarator_kind, int *, bool);
|
||||
(cp_parser *, cp_parser_declarator_kind, int *, bool, bool);
|
||||
static enum tree_code cp_parser_ptr_operator
|
||||
(cp_parser *, tree *, cp_cv_quals *, tree *);
|
||||
static cp_cv_quals cp_parser_cv_qualifier_seq_opt
|
||||
@ -10014,7 +10014,8 @@ cp_parser_condition (cp_parser* parser)
|
||||
declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
/*ctor_dtor_or_conv_p=*/NULL,
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
/*member_p=*/false,
|
||||
/*friend_p=*/false);
|
||||
/* Parse the attributes. */
|
||||
attributes = cp_parser_attributes_opt (parser);
|
||||
/* Parse the asm-specification. */
|
||||
@ -14160,7 +14161,8 @@ cp_parser_explicit_instantiation (cp_parser* parser)
|
||||
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
/*ctor_dtor_or_conv_p=*/NULL,
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
/*member_p=*/false,
|
||||
/*friend_p=*/false);
|
||||
if (declares_class_or_enum & 2)
|
||||
cp_parser_check_for_definition_in_return_type (declarator,
|
||||
decl_specifiers.type,
|
||||
@ -16570,7 +16572,7 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
&ctor_dtor_or_conv_p,
|
||||
/*parenthesized_p=*/NULL,
|
||||
member_p);
|
||||
member_p, /*friend_p=*/false);
|
||||
/* Gather up the deferred checks. */
|
||||
stop_deferring_access_checks ();
|
||||
|
||||
@ -16958,14 +16960,16 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||
If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
|
||||
the declarator is a direct-declarator of the form "(...)".
|
||||
|
||||
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. */
|
||||
|
||||
static cp_declarator *
|
||||
cp_parser_declarator (cp_parser* parser,
|
||||
cp_parser_declarator_kind dcl_kind,
|
||||
int* ctor_dtor_or_conv_p,
|
||||
bool* parenthesized_p,
|
||||
bool member_p)
|
||||
bool member_p, bool friend_p)
|
||||
{
|
||||
cp_declarator *declarator;
|
||||
enum tree_code code;
|
||||
@ -17005,7 +17009,8 @@ cp_parser_declarator (cp_parser* parser,
|
||||
declarator = cp_parser_declarator (parser, dcl_kind,
|
||||
/*ctor_dtor_or_conv_p=*/NULL,
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
/*member_p=*/false,
|
||||
friend_p);
|
||||
|
||||
/* If we are parsing an abstract-declarator, we must handle the
|
||||
case where the dependent declarator is absent. */
|
||||
@ -17024,7 +17029,7 @@ cp_parser_declarator (cp_parser* parser,
|
||||
CPP_OPEN_PAREN);
|
||||
declarator = cp_parser_direct_declarator (parser, dcl_kind,
|
||||
ctor_dtor_or_conv_p,
|
||||
member_p);
|
||||
member_p, friend_p);
|
||||
}
|
||||
|
||||
if (gnu_attributes && declarator && declarator != cp_error_declarator)
|
||||
@ -17058,14 +17063,14 @@ cp_parser_declarator (cp_parser* parser,
|
||||
we are parsing a direct-declarator. It is
|
||||
CP_PARSER_DECLARATOR_EITHER, if we can accept either - in the case
|
||||
of ambiguity we prefer an abstract declarator, as per
|
||||
[dcl.ambig.res]. CTOR_DTOR_OR_CONV_P and MEMBER_P are as for
|
||||
cp_parser_declarator. */
|
||||
[dcl.ambig.res]. CTOR_DTOR_OR_CONV_P, MEMBER_P, and FRIEND_P are
|
||||
as for cp_parser_declarator. */
|
||||
|
||||
static cp_declarator *
|
||||
cp_parser_direct_declarator (cp_parser* parser,
|
||||
cp_parser_declarator_kind dcl_kind,
|
||||
int* ctor_dtor_or_conv_p,
|
||||
bool member_p)
|
||||
bool member_p, bool friend_p)
|
||||
{
|
||||
cp_token *token;
|
||||
cp_declarator *declarator = NULL;
|
||||
@ -17246,7 +17251,7 @@ cp_parser_direct_declarator (cp_parser* parser,
|
||||
declarator
|
||||
= cp_parser_declarator (parser, dcl_kind, ctor_dtor_or_conv_p,
|
||||
/*parenthesized_p=*/NULL,
|
||||
member_p);
|
||||
member_p, friend_p);
|
||||
parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
|
||||
first = false;
|
||||
/* Expect a `)'. */
|
||||
@ -17492,6 +17497,24 @@ cp_parser_direct_declarator (cp_parser* parser,
|
||||
for an anonymous type, even if the type
|
||||
got a name for linkage purposes. */
|
||||
!TYPE_WAS_ANONYMOUS (class_type)
|
||||
/* Handle correctly (c++/19200):
|
||||
|
||||
struct S {
|
||||
struct T{};
|
||||
friend void S(T);
|
||||
};
|
||||
|
||||
and also:
|
||||
|
||||
namespace N {
|
||||
void S();
|
||||
}
|
||||
|
||||
struct S {
|
||||
friend void N::S();
|
||||
}; */
|
||||
&& !(friend_p
|
||||
&& class_type != qualifying_scope)
|
||||
&& constructor_name_p (unqualified_name,
|
||||
class_type))
|
||||
{
|
||||
@ -18035,7 +18058,8 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg,
|
||||
abstract_declarator
|
||||
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_ABSTRACT, NULL,
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
/*member_p=*/false,
|
||||
/*friend_p=*/false);
|
||||
/* Check to see if there really was a declarator. */
|
||||
if (!cp_parser_parse_definitely (parser))
|
||||
abstract_declarator = NULL;
|
||||
@ -18610,7 +18634,8 @@ cp_parser_parameter_declaration (cp_parser *parser,
|
||||
CP_PARSER_DECLARATOR_EITHER,
|
||||
/*ctor_dtor_or_conv_p=*/NULL,
|
||||
parenthesized_p,
|
||||
/*member_p=*/false);
|
||||
/*member_p=*/false,
|
||||
/*friend_p=*/false);
|
||||
parser->default_arg_ok_p = saved_default_arg_ok_p;
|
||||
/* After the declarator, allow more attributes. */
|
||||
decl_specifiers.attributes
|
||||
@ -20446,7 +20471,8 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
&ctor_dtor_or_conv_p,
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/true);
|
||||
/*member_p=*/true,
|
||||
friend_p);
|
||||
|
||||
/* If something went wrong parsing the declarator, make sure
|
||||
that we at least consume some tokens. */
|
||||
@ -21274,7 +21300,8 @@ cp_parser_exception_declaration (cp_parser* parser)
|
||||
declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER,
|
||||
/*ctor_dtor_or_conv_p=*/NULL,
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
/*member_p=*/false,
|
||||
/*friend_p=*/false);
|
||||
|
||||
/* Restore the saved message. */
|
||||
parser->type_definition_forbidden_message = saved_message;
|
||||
@ -24820,7 +24847,8 @@ cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
|
||||
cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
&ctor_dtor_or_conv_p,
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/true);
|
||||
/*member_p=*/true,
|
||||
/*friend_p=*/false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -26106,7 +26134,8 @@ cp_parser_objc_class_ivars (cp_parser* parser)
|
||||
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
&ctor_dtor_or_conv_p,
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
/*member_p=*/false,
|
||||
/*friend_p=*/false);
|
||||
}
|
||||
|
||||
/* Look for attributes that apply to the ivar. */
|
||||
@ -26657,7 +26686,7 @@ cp_parser_objc_struct_declaration (cp_parser *parser)
|
||||
|
||||
/* Parse the declarator. */
|
||||
declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
NULL, NULL, false);
|
||||
NULL, NULL, false, false);
|
||||
|
||||
/* Look for attributes that apply to the ivar. */
|
||||
attributes = cp_parser_attributes_opt (parser);
|
||||
@ -29170,7 +29199,8 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
|
||||
CP_PARSER_DECLARATOR_NAMED,
|
||||
/*ctor_dtor_or_conv_p=*/NULL,
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
/*member_p=*/false,
|
||||
/*friend_p=*/false);
|
||||
attributes = cp_parser_attributes_opt (parser);
|
||||
asm_specification = cp_parser_asm_specification_opt (parser);
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
2014-06-11 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/19200
|
||||
* g++.dg/parse/friend9.C: New.
|
||||
* g++.dg/parse/friend10.C: Likewise.
|
||||
* g++.dg/parse/friend7.C: Adjust.
|
||||
|
||||
2014-06-11 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/61452
|
||||
|
9
gcc/testsuite/g++.dg/parse/friend10.C
Normal file
9
gcc/testsuite/g++.dg/parse/friend10.C
Normal file
@ -0,0 +1,9 @@
|
||||
// PR c++/19200
|
||||
|
||||
namespace N {
|
||||
void S();
|
||||
}
|
||||
|
||||
struct S {
|
||||
friend void N::S();
|
||||
};
|
@ -17,16 +17,16 @@ struct B
|
||||
|
||||
struct C
|
||||
{
|
||||
friend int C (); // { dg-error "return type|in friend decl" }
|
||||
friend int C ();
|
||||
friend int ~C (); // { dg-error "return type|in friend decl" }
|
||||
friend int C (const C &); // { dg-error "return type|in friend decl" }
|
||||
friend int C (const C &);
|
||||
};
|
||||
|
||||
struct D
|
||||
{
|
||||
friend int D () {} // { dg-error "return type|in friend decl" }
|
||||
friend int D () {}
|
||||
friend int ~D () {} // { dg-error "return type|in friend decl" }
|
||||
friend int D (const D &) {} // { dg-error "return type|in friend decl" }
|
||||
friend int D (const D &) {}
|
||||
};
|
||||
|
||||
struct E
|
||||
|
6
gcc/testsuite/g++.dg/parse/friend9.C
Normal file
6
gcc/testsuite/g++.dg/parse/friend9.C
Normal file
@ -0,0 +1,6 @@
|
||||
// PR c++/19200
|
||||
|
||||
struct S {
|
||||
struct T{};
|
||||
friend void S(T);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user