Skip to content

Commit

Permalink
Allow 'inline' on some declarations in MS compatibility mode (#125250) (
Browse files Browse the repository at this point in the history
#125275)

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

(cherry picked from commit ef91cae)
  • Loading branch information
AaronBallman authored Feb 1, 2025
1 parent 184d178 commit fe005eb
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 4 deletions.
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,8 @@ 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
- Extend clang's ``<limits.h>`` to define ``LONG_LONG_*`` macros for Android's bionic.
- Macro ``__STDC_NO_THREADS__`` is no longer necessary for MSVC 2022 1939 and later.
- Exposed the the ``__nullptr`` keyword as an alias for ``nullptr`` in all C language modes.
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,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]>;
Expand All @@ -1324,7 +1326,7 @@ def Microsoft : DiagGroup<"microsoft",
MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag,
MicrosoftCommentPaste, MicrosoftEndOfFile, MicrosoftStaticAssert,
MicrosoftInitFromPredefined, MicrosoftStringLiteralFromPredefined,
MicrosoftInconsistentDllImport]>;
MicrosoftInconsistentDllImport, MicrosoftInlineOnNonFunction]>;

def ClangClPch : DiagGroup<"clang-cl-pch">;

Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
16 changes: 14 additions & 2 deletions clang/test/Sema/MicrosoftCompatibility.c
Original file line number Diff line number Diff line change
@@ -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}}
Expand Down Expand Up @@ -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}}
7 changes: 7 additions & 0 deletions clang/test/Sema/MicrosoftCompatibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}}

0 comments on commit fe005eb

Please sign in to comment.