Author: AZero13
Date: 2026-09-08T03:05:01Z
New Revision: 2edc68ceee32011f8f2d28fb97b64bc9e3a3b521

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

LOG: [clang] Reject __super when preceded by a scope specifier (#221492)

The `__super` keyword is an MSVC extension that refers to the base class
of the current class context. It is fundamentally invalid for `__super`
to be qualified by another scope specifier (e.g. `::__super` or
`N::__super`).

Fixes #212988

---------

Co-authored-by: Shengxin Pei <[email protected]>
Co-authored-by: Corentin Jabot <[email protected]>

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.md
    clang/lib/Parse/ParseExprCXX.cpp
    clang/test/Parser/recovery.cpp
    clang/test/SemaCXX/MicrosoftSuper.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 38d5ecc09c52d..cd59d6e942a35 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -556,6 +556,7 @@ features cannot lower the translation-unit ABI level;
 
 - Fixed a bug where top-level CV qualifiers (such as ``const``) were dropped 
from pointers modified by Microsoft pointer attributes (like ``__ptr32`` and 
``__ptr64``) and WebAssembly's ``__funcref``.
 
+- Fixed a bug where we accepted ``__super`` being qualified by a scope 
specifier, causing codegen to assertion fail elsewhere. (#GH212988)
 - Fixed an issue where we tried to compare invalid NTTPs for variable 
declarations, which ended up in hitting an assertion with a constrained 
non-plain-auto NTTP, which we don't quite implement yet. (#GH208658)
 
 - Fixed a crash when a using-declaration naming an unresolvable member of a

diff  --git a/clang/lib/Parse/ParseExprCXX.cpp 
b/clang/lib/Parse/ParseExprCXX.cpp
index ae741af7249cf..63f7938c6fc64 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -153,7 +153,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(
     }
   }
 
-  if (Tok.is(tok::kw___super)) {
+  if (!HasScopeSpecifier && Tok.is(tok::kw___super)) {
     SourceLocation SuperLoc = ConsumeToken();
     if (!Tok.is(tok::coloncolon)) {
       Diag(Tok.getLocation(), diag::err_expected_coloncolon_after_super);

diff  --git a/clang/test/Parser/recovery.cpp b/clang/test/Parser/recovery.cpp
index 0637d4cbe72ae..be0b847b9ceb7 100644
--- a/clang/test/Parser/recovery.cpp
+++ b/clang/test/Parser/recovery.cpp
@@ -210,7 +210,7 @@ namespace InvalidEmptyNames {
 // These shouldn't crash, the diagnostics aren't important.
 struct ::, struct ::; // expected-error 2 {{expected identifier}} 
expected-error 2 {{declaration of anonymous struct must be a definition}} 
expected-warning {{declaration does not declare anything}}
 enum ::, enum ::; // expected-error 2 {{expected identifier}}
-struct ::__super, struct ::__super; // expected-error 2 {{expected 
identifier}} expected-error 2 {{expected '::' after '__super'}}
+struct ::__super, struct ::__super; // expected-error 2 {{expected 
identifier}} expected-error 2 {{declaration of anonymous struct must be a 
definition}} expected-warning {{declaration does not declare anything}}
 struct ::template foo, struct ::template bar; // expected-error 2 {{expected 
identifier}} expected-error 2 {{declaration of anonymous struct must be a 
definition}} expected-warning {{declaration does not declare anything}}
 struct ::foo struct::; // expected-error {{no struct named 'foo' in the global 
namespace}} expected-error {{expected identifier}}
 class :: : {} a;  // expected-error {{expected identifier}} expected-error 
{{expected class name}}

diff  --git a/clang/test/SemaCXX/MicrosoftSuper.cpp 
b/clang/test/SemaCXX/MicrosoftSuper.cpp
index d117b93523363..98f087708d72d 100644
--- a/clang/test/SemaCXX/MicrosoftSuper.cpp
+++ b/clang/test/SemaCXX/MicrosoftSuper.cpp
@@ -21,6 +21,13 @@ struct Base1 {
   typedef int XXX;
 };
 
+struct InvalidGlobalQualifier : Base1 {
+  // A parser that drops the global qualifier is left with the valid
+  // declaration `__super::XXX x;` and accepts this line silently; expecting
+  // a diagnostic here catches that even in builds without assertions.
+  ::__super::XXX x; // expected-error {{expected unqualified-id}}
+};
+
 struct Derived : Base1 {
   __super::XXX x;
   typedef __super::XXX Type;


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to