+2019-05-25 Marek Polacek <polacek@redhat.com>
+
+ Backported from mainline
+ 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-20 Jonathan Wakely <jwakely@redhat.com>
Backported from mainline
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,
--- /dev/null
+// 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;
--- /dev/null
+// 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);
+};