[clang] 9d872cb - [clang] Fix crashes with inheritance model keywords (#228207)

via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 2 04:55:23 PDT 2026


Author: Aaron Ballman
Date: 2026-10-02T11:55:11Z
New Revision: 9d872cbb70f3f525a39f2b964597ecfd2b8735e4

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

LOG: [clang] Fix crashes with inheritance model keywords (#228207)

The inheritance model keywords support a single underscore alias, but
that alias was never added to Attr.td. When we added typo correction
support for attributes in Clang 21, this uncovered a bug with these
keywords when a single underscore variant was used because the
hasAttribute() logic didn't know about these spellings. This adds the
correct spellings for the aliases to Attr.td.

While working on that, I noticed that we were missing an alias for
_single_inheritance, which is supported by MSVC, so that was added as a
drive-by fix.

Fixes #228003

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.md
    clang/include/clang/Basic/Attr.td
    clang/include/clang/Basic/TokenKinds.def
    clang/test/Parser/MicrosoftExtensions.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index acdf563f7d0bf8..6afaa6675be7cd 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -296,6 +296,8 @@ features cannot lower the translation-unit ABI level;
 
 - Clang now recognizes the `[[gnu::flag_enum]]` attribute and treats it equivalent to `[[clang::flag_enum]]`
 
+- Clang now accepts `_single_inheritance` under `-fms-compatibility` as an alias for `__single_inheritance`; `_multiple_inheritance` and `_virtual_inheritance` were already correctly supported as aliases.
+
 ### Improvements to Clang's diagnostics
 
 - `-Wfortify-source` now diagnoses when `strlcat`, `__builtin_strlcat`, `strlcpy`, or
@@ -583,6 +585,7 @@ features cannot lower the translation-unit ABI level;
   (e.g. `({ s.b; })`) was not subject to integer promotion, unlike an ordinary
   bit-field access. (#GH221542)
 - No longer crashing due to follow-on diagnostics when there is an invalid operand in a logical operator involving a vector operand. (#GH227588)
+- Fixed a crash due to typo correction mishandling custom keywords `_virtual_inheritance` and `_multiple_inheritance` in `-fms-compatibility` mode. (#GH228003)
   
 #### Bug Fixes to Compiler Builtins
 

diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 48dda036f87105..4ef0bd2b5ca7c1 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4670,7 +4670,16 @@ def MSInheritance : InheritableAttr {
   let Spellings = [CustomKeyword<"__single_inheritance">,
                    CustomKeyword<"__multiple_inheritance">,
                    CustomKeyword<"__virtual_inheritance">,
-                   CustomKeyword<"__unspecified_inheritance">];
+                   CustomKeyword<"__unspecified_inheritance">,
+                   // The single underscore spellings are aliases defined in
+                   // TokenKinds.def; they must come *after* all of the other
+                   // spellings because otherwise the MSInheritanceModel
+                   // enumeration will break (we're relying on token
+                   // normalization converting the alias to the normal form).
+                   CustomKeyword<"_single_inheritance">,
+                   CustomKeyword<"_multiple_inheritance">,
+                   CustomKeyword<"_virtual_inheritance">
+                   ];
   let AdditionalMembers = [{
   MSInheritanceModel getInheritanceModel() const {
     // The spelling enum should agree with MSInheritanceModel.

diff  --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 97e5915bcd0d5e..213f2492d96f40 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -657,6 +657,7 @@ ALIAS("_multiple_inheritance", __multiple_inheritance, KEYMSCOMPAT)
 ALIAS("_ptr32"           , __ptr32      , KEYMSCOMPAT)
 ALIAS("_ptr64"           , __ptr64      , KEYMSCOMPAT)
 ALIAS("_restrict"        , restrict     , KEYMSCOMPAT)
+ALIAS("_single_inheritance", __single_inheritance, KEYMSCOMPAT)
 ALIAS("_stdcall"         , __stdcall    , KEYMS | KEYBORLAND)
 ALIAS("_thiscall"        , __thiscall   , KEYMS)
 ALIAS("_try"             , __try        , KEYMSCOMPAT)

diff  --git a/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp
index e32d7fae6af399..ee23596df46f63 100644
--- a/clang/test/Parser/MicrosoftExtensions.cpp
+++ b/clang/test/Parser/MicrosoftExtensions.cpp
@@ -349,6 +349,13 @@ namespace Inheritance {
   class __single_inheritance A;
   class __multiple_inheritance B;
   class __virtual_inheritance C;
+
+  // The single underscore variants are the same as the double underscore ones.
+  // Some of these would crash due to typo correction because the spellings
+  // were missing from Attr.td but supported by TokenKinds.def. See GH228003.
+  class _single_inheritance D;
+  class _multiple_inheritance E;
+  class _virtual_inheritance F;
 }
 
 struct StructWithProperty {


        


More information about the cfe-commits mailing list