[clang] [clang][ObjectiveC] Fix Parsing Types with the `::` Optional Scope Specifier (PR #119908)

Qiongsi Wu via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 18 14:31:54 PST 2024


https://github.com/qiongsiwu updated https://github.com/llvm/llvm-project/pull/119908

>From 63c424414c1814ec9b4c3c5a459bfe1be684586d Mon Sep 17 00:00:00 2001
From: Qiongsi Wu <qiongsi_wu at apple.com>
Date: Fri, 13 Dec 2024 09:41:41 -0800
Subject: [PATCH 1/4] Fix parsing :: in method parameter type.

---
 clang/lib/Parse/Parser.cpp          | 8 +++++++-
 clang/test/Parser/objc-coloncolon.m | 5 +++++
 2 files changed, 12 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Parser/objc-coloncolon.m

diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 36e56a92c3092e..aa78d702553172 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -2222,8 +2222,14 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(
     }
   }
 
-  if (SS.isEmpty())
+  if (SS.isEmpty()) {
+    if (getLangOpts().ObjC && Tok.is(tok::coloncolon)) {
+      // ObjectiveC does not allow :: as as a scope token.
+      Diag(ConsumeToken(), diag::err_expected_type);
+      return true;
+    }
     return false;
+  }
 
   // A C++ scope specifier that isn't followed by a typename.
   AnnotateScopeToken(SS, IsNewScope);
diff --git a/clang/test/Parser/objc-coloncolon.m b/clang/test/Parser/objc-coloncolon.m
new file mode 100644
index 00000000000000..e8a09898263bb3
--- /dev/null
+++ b/clang/test/Parser/objc-coloncolon.m
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -x objective-c -fsyntax-only -verify %s
+
+ at interface A
+- (instancetype)init:(::A *) foo; // expected-error {{expected a type}} 
+ at end

>From ec903eb3fcd18ba53af901582060bd61b13cf324 Mon Sep 17 00:00:00 2001
From: Qiongsi Wu <qiongsi_wu at apple.com>
Date: Mon, 16 Dec 2024 09:34:52 -0800
Subject: [PATCH 2/4] Fix ObjectiveC++

---
 clang/lib/Parse/Parser.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index aa78d702553172..8ba6a5dce8a994 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -2223,7 +2223,8 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(
   }
 
   if (SS.isEmpty()) {
-    if (getLangOpts().ObjC && Tok.is(tok::coloncolon)) {
+    if (getLangOpts().ObjC && !getLangOpts().CPlusPlus &&
+        Tok.is(tok::coloncolon)) {
       // ObjectiveC does not allow :: as as a scope token.
       Diag(ConsumeToken(), diag::err_expected_type);
       return true;

>From 66c3b0b874f5a962ff902c43d33fbb22c658780c Mon Sep 17 00:00:00 2001
From: Qiongsi Wu <qiongsi_wu at apple.com>
Date: Wed, 18 Dec 2024 09:49:15 -0800
Subject: [PATCH 3/4] Address code review.

---
 clang/docs/ReleaseNotes.rst            |  3 +++
 clang/test/Parser/objc-coloncolon.m    | 12 ++++++++++--
 clang/test/Parser/objcxx-coloncolon.mm |  9 +++++++++
 3 files changed, 22 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Parser/objcxx-coloncolon.mm

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 26fa986810a4b8..d6d3149df07d87 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -675,6 +675,9 @@ Improvements to Clang's diagnostics
       views.push_back(std::string("123")); // warning
     }
 
+- Fixed a bug where Clang hangs on unsupported optional scope specifier ``::`` when parsing
+  Objective-C. Clang now emits a diagnostic message instead of hanging.
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/test/Parser/objc-coloncolon.m b/clang/test/Parser/objc-coloncolon.m
index e8a09898263bb3..68b54ef5229af5 100644
--- a/clang/test/Parser/objc-coloncolon.m
+++ b/clang/test/Parser/objc-coloncolon.m
@@ -1,5 +1,13 @@
-// RUN: %clang_cc1 -x objective-c -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x objective-c -fsyntax-only -Wno-objc-root-class -verify %s
+
+int GV = 42;
 
 @interface A
-- (instancetype)init:(::A *) foo; // expected-error {{expected a type}} 
++ (int) getGV;
+- (instancetype)init:(::A *) foo; // expected-error {{expected a type}}
+ at end
+
+ at implementation A
++ (int) getGV { return ::GV; } // expected-error {{expected a type}}
+- (instancetype)init:(::A *) foo { return self; } // expected-error {{expected a type}}
 @end
diff --git a/clang/test/Parser/objcxx-coloncolon.mm b/clang/test/Parser/objcxx-coloncolon.mm
new file mode 100644
index 00000000000000..864a7df8400c1c
--- /dev/null
+++ b/clang/test/Parser/objcxx-coloncolon.mm
@@ -0,0 +1,9 @@
+// Test to make sure the parser does not get stuck on the optional
+// scope specifier on the type B.
+// RUN: %clang_cc1 -fsyntax-only %s
+
+class B;
+
+ at interface A
+- (void) init:(::B *) foo;
+ at end

>From 2e0667d1f21f406be8c9ae1f10eb12f60296ddd8 Mon Sep 17 00:00:00 2001
From: Qiongsi Wu <qiongsi_wu at apple.com>
Date: Wed, 18 Dec 2024 11:10:16 -0800
Subject: [PATCH 4/4] Modifying the test to include valid Objective-C with

---
 clang/test/Parser/objc-coloncolon.m | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/clang/test/Parser/objc-coloncolon.m b/clang/test/Parser/objc-coloncolon.m
index 68b54ef5229af5..04a24fd81ec08f 100644
--- a/clang/test/Parser/objc-coloncolon.m
+++ b/clang/test/Parser/objc-coloncolon.m
@@ -8,6 +8,12 @@ - (instancetype)init:(::A *) foo; // expected-error {{expected a type}}
 @end
 
 @implementation A
+- (void)performSelector:(SEL)selector {}
+- (void)double:(int)firstArg :(int)secondArg colon:(int)thirdArg {}
+- (void)test {
+  // The `::` below should not trigger an error.
+  [self performSelector:@selector(double::colon:)];
+}
 + (int) getGV { return ::GV; } // expected-error {{expected a type}}
 - (instancetype)init:(::A *) foo { return self; } // expected-error {{expected a type}}
 @end



More information about the cfe-commits mailing list