https://github.com/a-tarasyuk updated 
https://github.com/llvm/llvm-project/pull/122621

>From b2c656afdf99eff52d019b68fcbbc6ce4bbdd7d3 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Sun, 12 Jan 2025 00:51:47 +0200
Subject: [PATCH 1/8] [Clang] disallow the use of asterisks preceding
 constructor and destructor names

---
 clang/docs/ReleaseNotes.rst                      |  1 +
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  4 ++++
 clang/lib/Sema/SemaDeclCXX.cpp                   | 13 +++++++++++++
 clang/test/SemaCXX/constructor.cpp               | 10 ++++++++++
 clang/test/SemaCXX/destructor.cpp                |  7 +++++++
 5 files changed, 35 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 197b3692b8a181..9e5bbbf6dc055a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -764,6 +764,7 @@ Improvements to Clang's diagnostics
       scope.Unlock();
       require(scope); // Warning!  Requires mu1.
     }
+- Clang now disallows the use of asterisks preceding constructor and 
destructor names (#GH121706).
 
 Improvements to Clang's time-trace
 ----------------------------------
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d4e897868f1a9a..ec0be4ea8b6ce0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2202,6 +2202,8 @@ def err_invalid_qualified_constructor : Error<
   "'%0' qualifier is not allowed on a constructor">;
 def err_ref_qualifier_constructor : Error<
   "ref-qualifier '%select{&&|&}0' is not allowed on a constructor">;
+def err_invalid_constructor_decl : Error<
+  "invalid constructor declaration">;
 
 def err_constructor_return_type : Error<
   "constructor cannot have a return type">;
@@ -2223,6 +2225,8 @@ def err_destructor_not_member : Error<
 def err_destructor_cannot_be : Error<"destructor cannot be declared '%0'">;
 def err_invalid_qualified_destructor : Error<
   "'%0' qualifier is not allowed on a destructor">;
+def err_invalid_destructor_decl : Error<
+  "invalid destructor declaration">;
 def err_ref_qualifier_destructor : Error<
   "ref-qualifier '%select{&&|&}0' is not allowed on a destructor">;
 def err_destructor_return_type : Error<"destructor cannot have a return type">;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index c4bee44f5ec048..bb6f6e14713d9b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -10757,6 +10757,17 @@ static void checkMethodTypeQualifiers(Sema &S, 
Declarator &D, unsigned DiagID) {
   }
 }
 
+static void checkMethodPointerType(Sema &S, Declarator &D, unsigned DiagID) {
+  if (D.getNumTypeObjects() > 0) {
+    DeclaratorChunk &Chunk = D.getTypeObject(D.getNumTypeObjects() - 1);
+    if (Chunk.Kind == DeclaratorChunk::Pointer) {
+      SourceLocation PointerLoc = Chunk.getSourceRange().getBegin();
+      S.Diag(PointerLoc, DiagID) << Chunk.getSourceRange();
+      D.setInvalidType();
+    }
+  }
+}
+
 QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
                                           StorageClass &SC) {
   bool isVirtual = D.getDeclSpec().isVirtualSpecified();
@@ -10792,6 +10803,7 @@ QualType Sema::CheckConstructorDeclarator(Declarator 
&D, QualType R,
   }
 
   checkMethodTypeQualifiers(*this, D, diag::err_invalid_qualified_constructor);
+  checkMethodPointerType(*this, D, diag::err_invalid_constructor_decl);
 
   // C++0x [class.ctor]p4:
   //   A constructor shall not be declared with a ref-qualifier.
@@ -10958,6 +10970,7 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, 
QualType R,
   }
 
   checkMethodTypeQualifiers(*this, D, diag::err_invalid_qualified_destructor);
+  checkMethodPointerType(*this, D, diag::err_invalid_destructor_decl);
 
   // C++0x [class.dtor]p2:
   //   A destructor shall not be declared with a ref-qualifier.
diff --git a/clang/test/SemaCXX/constructor.cpp 
b/clang/test/SemaCXX/constructor.cpp
index abd7dbe18a0e6a..c6df7be25c1fac 100644
--- a/clang/test/SemaCXX/constructor.cpp
+++ b/clang/test/SemaCXX/constructor.cpp
@@ -96,3 +96,13 @@ namespace PR38286 {
   template<typename> struct C; // expected-note {{non-type declaration found}}
   template<typename T> C<T>::~C() {} // expected-error {{identifier 'C' after 
'~' in destructor name does not name a type}}
 }
+
+namespace GH121706 {
+struct S {
+  *S();  // expected-error {{invalid constructor declaration}}
+  **S(); // expected-error {{invalid constructor declaration}}
+
+  **S(const S &); // expected-error {{invalid constructor declaration}}
+  *S(S &&);       // expected-error {{invalid constructor declaration}}
+};
+}
diff --git a/clang/test/SemaCXX/destructor.cpp 
b/clang/test/SemaCXX/destructor.cpp
index dfcd1b033af5a2..f188e95c25d174 100644
--- a/clang/test/SemaCXX/destructor.cpp
+++ b/clang/test/SemaCXX/destructor.cpp
@@ -586,4 +586,11 @@ struct Y : X {} y1{ }; // expected-error {{call to 
implicitly-deleted default co
                        // expected-note {{default constructor of 'Y' is 
implicitly deleted because base class 'X' has no destructor}}
 }
 
+namespace GH121706 {
+struct S {
+  *~S();  // expected-error {{invalid destructor declaration}}
+  **~S(); // expected-error {{invalid destructor declaration}}
+};
+}
+
 #endif // BE_THE_HEADER

>From 144d0f35aabf0f02d0a90b8cd124f3f11bd65244 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Sun, 12 Jan 2025 14:50:59 +0200
Subject: [PATCH 2/8] skip invalid type checks

---
 clang/lib/Sema/SemaDeclCXX.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index bb6f6e14713d9b..b339ee95d75f15 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -10758,6 +10758,9 @@ static void checkMethodTypeQualifiers(Sema &S, 
Declarator &D, unsigned DiagID) {
 }
 
 static void checkMethodPointerType(Sema &S, Declarator &D, unsigned DiagID) {
+  if (D.isInvalidType())
+    return;
+
   if (D.getNumTypeObjects() > 0) {
     DeclaratorChunk &Chunk = D.getTypeObject(D.getNumTypeObjects() - 1);
     if (Chunk.Kind == DeclaratorChunk::Pointer) {

>From 13951a404b92b29969ea688343335b5f391fdb9e Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Mon, 13 Jan 2025 15:33:48 +0200
Subject: [PATCH 3/8] handle all invalid declarator chunks for ctor, dtor

---
 clang/lib/Sema/SemaDeclCXX.cpp | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index b339ee95d75f15..d4a96daea39a3c 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -10757,18 +10757,19 @@ static void checkMethodTypeQualifiers(Sema &S, 
Declarator &D, unsigned DiagID) {
   }
 }
 
-static void checkMethodPointerType(Sema &S, Declarator &D, unsigned DiagID) {
-  if (D.isInvalidType())
+static void diagnoseInvalidDeclaratorChunks(Sema &S, Declarator &D,
+                                            unsigned DiagID) {
+  if (D.isInvalidType() || D.getNumTypeObjects() <= 1)
     return;
 
-  if (D.getNumTypeObjects() > 0) {
-    DeclaratorChunk &Chunk = D.getTypeObject(D.getNumTypeObjects() - 1);
-    if (Chunk.Kind == DeclaratorChunk::Pointer) {
-      SourceLocation PointerLoc = Chunk.getSourceRange().getBegin();
-      S.Diag(PointerLoc, DiagID) << Chunk.getSourceRange();
-      D.setInvalidType();
-    }
-  }
+  DeclaratorChunk &Chunk = D.getTypeObject(D.getNumTypeObjects() - 1);
+  if (Chunk.Kind == DeclaratorChunk::Paren ||
+      Chunk.Kind == DeclaratorChunk::Function)
+    return;
+
+  SourceLocation PointerLoc = Chunk.getSourceRange().getBegin();
+  S.Diag(PointerLoc, DiagID) << Chunk.getSourceRange();
+  D.setInvalidType();
 }
 
 QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
@@ -10806,7 +10807,7 @@ QualType Sema::CheckConstructorDeclarator(Declarator 
&D, QualType R,
   }
 
   checkMethodTypeQualifiers(*this, D, diag::err_invalid_qualified_constructor);
-  checkMethodPointerType(*this, D, diag::err_invalid_constructor_decl);
+  diagnoseInvalidDeclaratorChunks(*this, D, 
diag::err_invalid_constructor_decl);
 
   // C++0x [class.ctor]p4:
   //   A constructor shall not be declared with a ref-qualifier.
@@ -10973,7 +10974,7 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, 
QualType R,
   }
 
   checkMethodTypeQualifiers(*this, D, diag::err_invalid_qualified_destructor);
-  checkMethodPointerType(*this, D, diag::err_invalid_destructor_decl);
+  diagnoseInvalidDeclaratorChunks(*this, D, diag::err_invalid_destructor_decl);
 
   // C++0x [class.dtor]p2:
   //   A destructor shall not be declared with a ref-qualifier.

>From 9389a6c0435a5316b8f0a5799a934b610750d484 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Mon, 13 Jan 2025 15:33:58 +0200
Subject: [PATCH 4/8] add additional tests

---
 clang/test/SemaCXX/constructor.cpp | 46 ++++++++++++++++++++++++++----
 clang/test/SemaCXX/destructor.cpp  | 45 +++++++++++++++++++++++++++--
 2 files changed, 83 insertions(+), 8 deletions(-)

diff --git a/clang/test/SemaCXX/constructor.cpp 
b/clang/test/SemaCXX/constructor.cpp
index c6df7be25c1fac..2e4e442d571993 100644
--- a/clang/test/SemaCXX/constructor.cpp
+++ b/clang/test/SemaCXX/constructor.cpp
@@ -98,11 +98,47 @@ namespace PR38286 {
 }
 
 namespace GH121706 {
-struct S {
-  *S();  // expected-error {{invalid constructor declaration}}
-  **S(); // expected-error {{invalid constructor declaration}}
+struct A {
+  *&A(); // expected-error {{invalid constructor declaration}}
+};
+
+struct B {
+  *&&B(); // expected-error {{invalid constructor declaration}}
+};
+
+struct C {
+  *const C(); // expected-error {{invalid constructor declaration}}
+};
+
+struct D {
+  *const *D(); // expected-error {{invalid constructor declaration}}
+};
+
+struct E {
+  *E::*E(); // expected-error {{invalid constructor declaration}}
+};
+
+struct F {
+  *F::*const F(); // expected-error {{invalid constructor declaration}}
+};
+
+struct G {
+  ****G(); // expected-error {{invalid constructor declaration}}
+};
+
+struct H {
+  **H(const H &); // expected-error {{invalid constructor declaration}}
+};
+
+struct I {
+  *I(I &&); // expected-error {{invalid constructor declaration}}
+};
+
+struct J {
+  *&(J)(); // expected-error {{invalid constructor declaration}}
+};
 
-  **S(const S &); // expected-error {{invalid constructor declaration}}
-  *S(S &&);       // expected-error {{invalid constructor declaration}}
+struct K {
+  **&&(K)(); // expected-error {{invalid constructor declaration}}
 };
 }
diff --git a/clang/test/SemaCXX/destructor.cpp 
b/clang/test/SemaCXX/destructor.cpp
index f188e95c25d174..589616ef8e437b 100644
--- a/clang/test/SemaCXX/destructor.cpp
+++ b/clang/test/SemaCXX/destructor.cpp
@@ -587,9 +587,48 @@ struct Y : X {} y1{ }; // expected-error {{call to 
implicitly-deleted default co
 }
 
 namespace GH121706 {
-struct S {
-  *~S();  // expected-error {{invalid destructor declaration}}
-  **~S(); // expected-error {{invalid destructor declaration}}
+struct A {
+  *&~A(); // expected-error {{invalid destructor declaration}}
+};
+
+struct B {
+  *&&~B(); // expected-error {{invalid destructor declaration}}
+};
+
+struct C {
+  *const ~C(); // expected-error {{invalid destructor declaration}}
+};
+
+struct D {
+  *const * ~D(); // expected-error {{invalid destructor declaration}}
+};
+
+struct E {
+  *E::*~E(); // expected-error {{invalid destructor declaration}}
+};
+
+struct F {
+  *F::*const ~F(); // expected-error {{invalid destructor declaration}}
+};
+
+struct G {
+  ****~G(); // expected-error {{invalid destructor declaration}}
+};
+
+struct H {
+  **~H(); // expected-error {{invalid destructor declaration}}
+};
+
+struct I {
+  *~I(); // expected-error {{invalid destructor declaration}}
+};
+
+struct J {
+  *&~J(); // expected-error {{invalid destructor declaration}}
+};
+
+struct K {
+  **&&~K(); // expected-error {{invalid destructor declaration}}
 };
 }
 

>From e5bd3e6daa6c8786e002d8a3e59609c299a71eea Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Mon, 13 Jan 2025 19:27:24 +0200
Subject: [PATCH 5/8] change diagnostic message

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 6 ++----
 clang/lib/Sema/SemaDeclCXX.cpp                   | 9 +++++----
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ec0be4ea8b6ce0..0fe1ad08c6388e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2202,8 +2202,8 @@ def err_invalid_qualified_constructor : Error<
   "'%0' qualifier is not allowed on a constructor">;
 def err_ref_qualifier_constructor : Error<
   "ref-qualifier '%select{&&|&}0' is not allowed on a constructor">;
-def err_invalid_constructor_decl : Error<
-  "invalid constructor declaration">;
+def err_invalid_ctor_dtor_decl : Error<
+  "invalid %select{constructor|destructor}0 declaration">;
 
 def err_constructor_return_type : Error<
   "constructor cannot have a return type">;
@@ -2225,8 +2225,6 @@ def err_destructor_not_member : Error<
 def err_destructor_cannot_be : Error<"destructor cannot be declared '%0'">;
 def err_invalid_qualified_destructor : Error<
   "'%0' qualifier is not allowed on a destructor">;
-def err_invalid_destructor_decl : Error<
-  "invalid destructor declaration">;
 def err_ref_qualifier_destructor : Error<
   "ref-qualifier '%select{&&|&}0' is not allowed on a destructor">;
 def err_destructor_return_type : Error<"destructor cannot have a return type">;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index d4a96daea39a3c..06cdc8044aef9d 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -10758,7 +10758,7 @@ static void checkMethodTypeQualifiers(Sema &S, 
Declarator &D, unsigned DiagID) {
 }
 
 static void diagnoseInvalidDeclaratorChunks(Sema &S, Declarator &D,
-                                            unsigned DiagID) {
+                                            unsigned Kind) {
   if (D.isInvalidType() || D.getNumTypeObjects() <= 1)
     return;
 
@@ -10768,7 +10768,8 @@ static void diagnoseInvalidDeclaratorChunks(Sema &S, 
Declarator &D,
     return;
 
   SourceLocation PointerLoc = Chunk.getSourceRange().getBegin();
-  S.Diag(PointerLoc, DiagID) << Chunk.getSourceRange();
+  S.Diag(PointerLoc, diag::err_invalid_ctor_dtor_decl)
+      << Kind << Chunk.getSourceRange();
   D.setInvalidType();
 }
 
@@ -10807,7 +10808,7 @@ QualType Sema::CheckConstructorDeclarator(Declarator 
&D, QualType R,
   }
 
   checkMethodTypeQualifiers(*this, D, diag::err_invalid_qualified_constructor);
-  diagnoseInvalidDeclaratorChunks(*this, D, 
diag::err_invalid_constructor_decl);
+  diagnoseInvalidDeclaratorChunks(*this, D, /*constructor*/ 0);
 
   // C++0x [class.ctor]p4:
   //   A constructor shall not be declared with a ref-qualifier.
@@ -10974,7 +10975,7 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, 
QualType R,
   }
 
   checkMethodTypeQualifiers(*this, D, diag::err_invalid_qualified_destructor);
-  diagnoseInvalidDeclaratorChunks(*this, D, diag::err_invalid_destructor_decl);
+  diagnoseInvalidDeclaratorChunks(*this, D, /*destructor*/ 1);
 
   // C++0x [class.dtor]p2:
   //   A destructor shall not be declared with a ref-qualifier.

>From 1fb1a8a95476bb583337873ecb795e9c3a81f419 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Mon, 13 Jan 2025 19:27:33 +0200
Subject: [PATCH 6/8] add tests

---
 clang/test/SemaCXX/constructor.cpp | 31 ++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/clang/test/SemaCXX/constructor.cpp 
b/clang/test/SemaCXX/constructor.cpp
index 2e4e442d571993..b069d55118f567 100644
--- a/clang/test/SemaCXX/constructor.cpp
+++ b/clang/test/SemaCXX/constructor.cpp
@@ -98,6 +98,7 @@ namespace PR38286 {
 }
 
 namespace GH121706 {
+
 struct A {
   *&A(); // expected-error {{invalid constructor declaration}}
 };
@@ -141,4 +142,34 @@ struct J {
 struct K {
   **&&(K)(); // expected-error {{invalid constructor declaration}}
 };
+
+struct L {
+  *L(L&& other); // expected-error {{invalid constructor declaration}}
+};
+
+struct M {
+  *M(M& other); // expected-error {{invalid constructor declaration}}
+};
+
+struct N {
+  int N(); // expected-error {{constructor cannot have a return type}}
+};
+
+struct O {
+  static O(); // expected-error {{constructor cannot be declared 'static'}}
+};
+
+struct P {
+  explicit P();
+};
+
+struct Q {
+  constexpr Q();
+};
+
+struct R {
+  R();
+  friend R::R();
+};
+
 }

>From a6766e9309742a531a3e78ebf63283ea7fa5ed68 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Mon, 13 Jan 2025 19:28:46 +0200
Subject: [PATCH 7/8] change release notes

---
 clang/docs/ReleaseNotes.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9e5bbbf6dc055a..948ab7271c7ac2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -764,7 +764,7 @@ Improvements to Clang's diagnostics
       scope.Unlock();
       require(scope); // Warning!  Requires mu1.
     }
-- Clang now disallows the use of asterisks preceding constructor and 
destructor names (#GH121706).
+- Diagnose invalid declarators in the declaration of constructors and 
destructors (#GH121706).
 
 Improvements to Clang's time-trace
 ----------------------------------

>From b3fd9b75907624f321aba24548b3a2f149b3350a Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Mon, 13 Jan 2025 23:56:46 +0200
Subject: [PATCH 8/8] add tests

---
 clang/test/SemaCXX/conversion-function.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/clang/test/SemaCXX/conversion-function.cpp 
b/clang/test/SemaCXX/conversion-function.cpp
index 749e2fc1b452b6..b653a3bf1a1d29 100644
--- a/clang/test/SemaCXX/conversion-function.cpp
+++ b/clang/test/SemaCXX/conversion-function.cpp
@@ -494,3 +494,10 @@ using Result = B<int>::Lookup<int>;
 using Result = int (A2<int>::*)();
 }
 #endif
+
+namespace GH121706 {
+struct S {
+  *operator int();   // expected-error {{cannot specify any part of a return 
type in the declaration of a conversion function; put the complete type after 
'operator'}}
+  **operator char(); // expected-error {{cannot specify any part of a return 
type in the declaration of a conversion function; put the complete type after 
'operator'}}
+};
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to