+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.
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
--- /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);
+};