diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a85ef60b7b58b..38c35aea3cf22 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -708,6 +708,9 @@ Improvements to Clang's diagnostics - Fix -Wdangling false positives on conditional operators (#120206). +- Fixed a bug where Clang hung on an 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/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 36e56a92c3092..8ba6a5dce8a99 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -2222,8 +2222,15 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec( } } - if (SS.isEmpty()) + if (SS.isEmpty()) { + 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; + } 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 0000000000000..04a24fd81ec08 --- /dev/null +++ b/clang/test/Parser/objc-coloncolon.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -x objective-c -fsyntax-only -Wno-objc-root-class -verify %s + +int GV = 42; + +@interface A ++ (int) getGV; +- (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 diff --git a/clang/test/Parser/objcxx-coloncolon.mm b/clang/test/Parser/objcxx-coloncolon.mm new file mode 100644 index 0000000000000..864a7df8400c1 --- /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; + +@interface A +- (void) init:(::B *) foo; +@end