[clang] d9be8a8 - [Clang] Allow omitting `typename` in befriended constructors parameters

Corentin Jabot via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 6 06:04:53 PDT 2023


Author: Corentin Jabot
Date: 2023-06-06T15:04:47+02:00
New Revision: d9be8a8a990d0194db5889c9b59c9ad49dd52cd7

URL: https://github.com/llvm/llvm-project/commit/d9be8a8a990d0194db5889c9b59c9ad49dd52cd7
DIFF: https://github.com/llvm/llvm-project/commit/d9be8a8a990d0194db5889c9b59c9ad49dd52cd7.diff

LOG: [Clang] Allow omitting `typename` in befriended constructors parameters

Fixes #63119

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

Differential Revision: https://reviews.llvm.org/D152242

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Parse/ParseDecl.cpp
    clang/test/CXX/temp/temp.res/p4.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8db6de896a121..9bbf270c27476 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -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
 ^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index da1d17d14c4c8..32085461ff8b7 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -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))) {

diff  --git a/clang/test/CXX/temp/temp.res/p4.cpp b/clang/test/CXX/temp/temp.res/p4.cpp
index 12ab355a26989..f54d8649f5da8 100644
--- a/clang/test/CXX/temp/temp.res/p4.cpp
+++ b/clang/test/CXX/temp/temp.res/p4.cpp
@@ -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);
+};
+}


        


More information about the cfe-commits mailing list