Skip to content

Commit

Permalink
[Clang] Allow omitting typename in befriended constructors parameters
Browse files Browse the repository at this point in the history
Fixes #63119

Reviewed By: #clang-language-wg, aaron.ballman

Differential Revision: https://reviews.llvm.org/D152242
  • Loading branch information
cor3ntin committed Jun 6, 2023
1 parent 3a87c15 commit d9be8a8
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Expand Up @@ -534,6 +534,9 @@ Bug Fixes to C++ Support
(`#62494 <https://github.com/llvm/llvm-project/issues/62494>`_)
- Fix handling of generic lambda used as template arguments.
(`#62611 <https://github.com/llvm/llvm-project/issues/62611>`_)
- Allow omitting ``typename`` in the parameter declaration of a friend
constructor declaration.
(`#63119 <https://github.com/llvm/llvm-project/issues/63119>`_)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/Parse/ParseDecl.cpp
Expand Up @@ -5820,9 +5820,12 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
// therefore, we know that this is a constructor.
// Due to an ambiguity with implicit typename, the above is not enough.
// Additionally, check to see if we are a friend.
// If we parsed a scope specifier as well as friend,
// we might be parsing a friend constructor.
bool IsConstructor = false;
if (isDeclarationSpecifier(IsFriend ? ImplicitTypenameContext::No
: ImplicitTypenameContext::Yes))
if (isDeclarationSpecifier(IsFriend && !SS.isSet()
? ImplicitTypenameContext::No
: ImplicitTypenameContext::Yes))
IsConstructor = true;
else if (Tok.is(tok::identifier) ||
(Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {
Expand Down
15 changes: 15 additions & 0 deletions clang/test/CXX/temp/temp.res/p4.cpp
Expand Up @@ -170,3 +170,18 @@ struct C {

template <typename T>
C<T>::C(T::type) {}

namespace GH63119 {
struct X {
X(int);
X(auto);
void f(int);
};
template<typename T> struct S {
friend X::X(T::type);
friend X::X(T::type = (int)(void(*)(typename T::type))(nullptr)); // expected-error {{friend declaration specifying a default argument must be a definition}}
friend X::X(T::type = (int)(void(*)(T::type))(nullptr)); // expected-error {{friend declaration specifying a default argument must be a definition}} \
// expected-error {{expected expression}}
friend void X::f(T::type);
};
}

0 comments on commit d9be8a8

Please sign in to comment.