[clang] ef91cae - Allow 'inline' on some declarations in MS compatibility mode (#125250)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 31 10:50:05 PST 2025
Author: Aaron Ballman
Date: 2025-01-31T13:50:01-05:00
New Revision: ef91caec2cf313624829114802cff92ae682e550
URL: https://github.com/llvm/llvm-project/commit/ef91caec2cf313624829114802cff92ae682e550
DIFF: https://github.com/llvm/llvm-project/commit/ef91caec2cf313624829114802cff92ae682e550.diff
LOG: Allow 'inline' on some declarations in MS compatibility mode (#125250)
Microsoft allows the 'inline' specifier on a typedef of a function type
in C modes. This is used by a system header (ufxclient.h), so instead
of giving a hard error, we diagnose with a warning. C++ mode and non-
Microsoft compatibility modes are not impacted.
Fixes https://github.com/llvm/llvm-project/issues/124869
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticGroups.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDecl.cpp
clang/test/Sema/MicrosoftCompatibility.c
clang/test/Sema/MicrosoftCompatibility.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8c290437fe16fe1..a220e57d0b32229 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -83,6 +83,9 @@ Resolutions to C++ Defect Reports
C Language Changes
------------------
+- Clang now allows an ``inline`` specifier on a typedef declaration of a
+ function type in Microsoft compatibility mode. #GH124869
+
C2y Feature Support
^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 527e588d46a049b..abb575002e11820 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1304,6 +1304,8 @@ def MicrosoftStaticAssert : DiagGroup<"microsoft-static-assert">;
def MicrosoftInitFromPredefined : DiagGroup<"microsoft-init-from-predefined">;
def MicrosoftStringLiteralFromPredefined : DiagGroup<
"microsoft-string-literal-from-predefined">;
+def MicrosoftInlineOnNonFunction : DiagGroup<
+ "microsoft-inline-on-non-function">;
// Aliases.
def : DiagGroup<"msvc-include", [MicrosoftInclude]>;
@@ -1322,7 +1324,7 @@ def Microsoft : DiagGroup<"microsoft",
MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag,
MicrosoftCommentPaste, MicrosoftEndOfFile, MicrosoftStaticAssert,
MicrosoftInitFromPredefined, MicrosoftStringLiteralFromPredefined,
- MicrosoftInconsistentDllImport]>;
+ MicrosoftInconsistentDllImport, MicrosoftInlineOnNonFunction]>;
def ClangClPch : DiagGroup<"clang-cl-pch">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 2ac3879a4caabca..00a94eb7a303671 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -482,6 +482,8 @@ def ext_use_out_of_scope_declaration : ExtWarn<
InGroup<DiagGroup<"out-of-scope-function">>;
def err_inline_non_function : Error<
"'inline' can only appear on functions%select{| and non-local variables}0">;
+def warn_ms_inline_non_function : ExtWarn<err_inline_non_function.Summary>,
+ InGroup<MicrosoftInlineOnNonFunction>;
def err_noreturn_non_function : Error<
"'_Noreturn' can only appear on functions">;
def warn_qual_return_type : Warning<
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f7b8b192a206c37..1755b37fc8f2950 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6681,7 +6681,10 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
DiagnoseFunctionSpecifiers(D.getDeclSpec());
if (D.getDeclSpec().isInlineSpecified())
- Diag(D.getDeclSpec().getInlineSpecLoc(), diag::err_inline_non_function)
+ Diag(D.getDeclSpec().getInlineSpecLoc(),
+ (getLangOpts().MSVCCompat && !getLangOpts().CPlusPlus)
+ ? diag::warn_ms_inline_non_function
+ : diag::err_inline_non_function)
<< getLangOpts().CPlusPlus17;
if (D.getDeclSpec().hasConstexprSpecifier())
Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr)
diff --git a/clang/test/Sema/MicrosoftCompatibility.c b/clang/test/Sema/MicrosoftCompatibility.c
index 9a1f050747f9d47..8d402d53e004d6f 100644
--- a/clang/test/Sema/MicrosoftCompatibility.c
+++ b/clang/test/Sema/MicrosoftCompatibility.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility -DMSVCCOMPAT -triple i686-pc-win32
-// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions -triple i686-pc-win32
+// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify=expected,compat -fms-compatibility -DMSVCCOMPAT -triple i686-pc-win32
+// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify=expected,ext -fms-extensions -triple i686-pc-win32
#ifdef MSVCCOMPAT
enum ENUM1; // expected-warning {{forward references to 'enum' types are a Microsoft extension}}
@@ -35,3 +35,15 @@ size_t x;
#else
size_t x; // expected-error {{unknown type name 'size_t'}}
#endif
+
+/* Microsoft allows inline, __inline, and __forceinline to appear on a typedef
+ of a function type; this is used in their system headers such as ufxclient.h
+ See GitHub #124869 for more details.
+ */
+typedef int inline Foo1(int); // compat-warning {{'inline' can only appear on functions}} \
+ ext-error {{'inline' can only appear on functions}}
+typedef int __inline Foo2(int); // compat-warning {{'inline' can only appear on functions}} \
+ ext-error {{'inline' can only appear on functions}}
+typedef int __forceinline Foo(int); // compat-warning {{'inline' can only appear on functions}} \
+ ext-error {{'inline' can only appear on functions}} \
+ expected-warning {{'__forceinline' attribute only applies to functions and statements}}
diff --git a/clang/test/Sema/MicrosoftCompatibility.cpp b/clang/test/Sema/MicrosoftCompatibility.cpp
index 90a45dfaaf176d9..391977e2765c5ce 100644
--- a/clang/test/Sema/MicrosoftCompatibility.cpp
+++ b/clang/test/Sema/MicrosoftCompatibility.cpp
@@ -8,3 +8,10 @@ struct cls {
};
char * cls::* __uptr wrong2 = &cls::m; // expected-error {{'__uptr' attribute cannot be used with pointers to members}}
+
+// Microsoft allows inline, __inline, and __forceinline to appear on a typedef
+// of a function type, but only in C. See GitHub #124869 for more details.
+typedef int inline Foo1(int); // expected-error {{'inline' can only appear on functions}}
+typedef int __inline Foo2(int); // expected-error {{'inline' can only appear on functions}}
+typedef int __forceinline Foo(int); // expected-error {{'inline' can only appear on functions}} \
+ expected-warning {{'__forceinline' attribute only applies to functions and statements}}
More information about the cfe-commits
mailing list