https://github.com/AaronBallman created https://github.com/llvm/llvm-project/pull/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 >From 247afa8e1311fd270875551196b3df1bffe5ea9d Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Fri, 31 Jan 2025 11:54:49 -0500 Subject: [PATCH] Allow 'inline' on some declarations in MS compatibility mode 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 #124869 --- clang/docs/ReleaseNotes.rst | 3 +++ clang/include/clang/Basic/DiagnosticGroups.td | 4 +++- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/lib/Sema/SemaDecl.cpp | 5 ++++- clang/test/Sema/MicrosoftCompatibility.c | 16 ++++++++++++++-- clang/test/Sema/MicrosoftCompatibility.cpp | 7 +++++++ 6 files changed, 33 insertions(+), 4 deletions(-) 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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits