Commit c3b2fdf9 by Marek Polacek Committed by Marek Polacek

PR c++/90572 - wrong disambiguation in friend declaration.

	* parser.c (cp_parser_constructor_declarator_p): Don't allow missing
	typename for friend declarations.

	* g++.dg/cpp2a/typename16.C: New test.
	* g++.dg/parse/friend13.C: New test.

From-SVN: r271619
parent e266148f
2019-05-25 Marek Polacek <polacek@redhat.com>
PR c++/90572 - wrong disambiguation in friend declaration.
* parser.c (cp_parser_constructor_declarator_p): Don't allow missing
typename for friend declarations.
2019-05-23 Jonathan Wakely <jwakely@redhat.com>
* cp-tree.h (CP_AGGREGATE_TYPE_P): Fix whitespace.
......
......@@ -27593,9 +27593,19 @@ cp_parser_constructor_declarator_p (cp_parser *parser, cp_parser_flags flags,
parser->num_template_parameter_lists = 0;
/* Look for the type-specifier. It's not optional, but its typename
might be. */
might be. Unless this is a friend declaration; we don't want to
treat
friend S (T::fn)(int);
as a constructor, but with P0634, we might assume a type when
looking for the type-specifier. It is actually a function named
`T::fn' that takes one parameter (of type `int') and returns a
value of type `S'. Constructors can be friends, but they must
use a qualified name. */
cp_parser_type_specifier (parser,
(flags & ~CP_PARSER_FLAGS_OPTIONAL),
(friend_p ? CP_PARSER_FLAGS_NONE
: (flags & ~CP_PARSER_FLAGS_OPTIONAL)),
/*decl_specs=*/NULL,
/*is_declarator=*/true,
/*declares_class_or_enum=*/NULL,
2019-05-25 Marek Polacek <polacek@redhat.com>
PR c++/90572 - wrong disambiguation in friend declaration.
* g++.dg/cpp2a/typename16.C: New test.
* g++.dg/parse/friend13.C: New test.
2019-05-24 Jakub Jelinek <jakub@redhat.com>
* c-c++-common/gomp/lastprivate-conditional-2.c (foo): Don't expect
......
// PR c++/90572
// { dg-do compile { target c++2a } }
struct X { X(int); };
template<typename T> struct S {
friend X::X(T::t);
};
struct W { using t = int; };
S<W> s;
// PR c++/90572
template <typename T> struct C {
friend C(T::fn)();
friend C(T::fn)(int);
friend C(T::fn)(int, int);
};
struct X { };
template<typename T>
struct B {
friend X(T::fn)();
friend X(T::fn)(int);
friend X(T::fn)(int, int);
};
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