Skip to content

Commit fe005eb

Browse files
authored
Allow 'inline' on some declarations in MS compatibility mode (llvm#125250) (llvm#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 llvm#124869 (cherry picked from commit ef91cae)
1 parent 184d178 commit fe005eb

File tree

6 files changed

+32
-4
lines changed

6 files changed

+32
-4
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ Resolutions to C++ Defect Reports
397397
C Language Changes
398398
------------------
399399

400+
- Clang now allows an ``inline`` specifier on a typedef declaration of a
401+
function type in Microsoft compatibility mode. #GH124869
400402
- Extend clang's ``<limits.h>`` to define ``LONG_LONG_*`` macros for Android's bionic.
401403
- Macro ``__STDC_NO_THREADS__`` is no longer necessary for MSVC 2022 1939 and later.
402404
- Exposed the the ``__nullptr`` keyword as an alias for ``nullptr`` in all C language modes.

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,8 @@ def MicrosoftStaticAssert : DiagGroup<"microsoft-static-assert">;
13061306
def MicrosoftInitFromPredefined : DiagGroup<"microsoft-init-from-predefined">;
13071307
def MicrosoftStringLiteralFromPredefined : DiagGroup<
13081308
"microsoft-string-literal-from-predefined">;
1309+
def MicrosoftInlineOnNonFunction : DiagGroup<
1310+
"microsoft-inline-on-non-function">;
13091311

13101312
// Aliases.
13111313
def : DiagGroup<"msvc-include", [MicrosoftInclude]>;
@@ -1324,7 +1326,7 @@ def Microsoft : DiagGroup<"microsoft",
13241326
MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag,
13251327
MicrosoftCommentPaste, MicrosoftEndOfFile, MicrosoftStaticAssert,
13261328
MicrosoftInitFromPredefined, MicrosoftStringLiteralFromPredefined,
1327-
MicrosoftInconsistentDllImport]>;
1329+
MicrosoftInconsistentDllImport, MicrosoftInlineOnNonFunction]>;
13281330

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

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,8 @@ def ext_use_out_of_scope_declaration : ExtWarn<
482482
InGroup<DiagGroup<"out-of-scope-function">>;
483483
def err_inline_non_function : Error<
484484
"'inline' can only appear on functions%select{| and non-local variables}0">;
485+
def warn_ms_inline_non_function : ExtWarn<err_inline_non_function.Summary>,
486+
InGroup<MicrosoftInlineOnNonFunction>;
485487
def err_noreturn_non_function : Error<
486488
"'_Noreturn' can only appear on functions">;
487489
def warn_qual_return_type : Warning<

clang/lib/Sema/SemaDecl.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6681,7 +6681,10 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
66816681
DiagnoseFunctionSpecifiers(D.getDeclSpec());
66826682

66836683
if (D.getDeclSpec().isInlineSpecified())
6684-
Diag(D.getDeclSpec().getInlineSpecLoc(), diag::err_inline_non_function)
6684+
Diag(D.getDeclSpec().getInlineSpecLoc(),
6685+
(getLangOpts().MSVCCompat && !getLangOpts().CPlusPlus)
6686+
? diag::warn_ms_inline_non_function
6687+
: diag::err_inline_non_function)
66856688
<< getLangOpts().CPlusPlus17;
66866689
if (D.getDeclSpec().hasConstexprSpecifier())
66876690
Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr)

clang/test/Sema/MicrosoftCompatibility.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility -DMSVCCOMPAT -triple i686-pc-win32
2-
// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions -triple i686-pc-win32
1+
// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify=expected,compat -fms-compatibility -DMSVCCOMPAT -triple i686-pc-win32
2+
// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify=expected,ext -fms-extensions -triple i686-pc-win32
33

44
#ifdef MSVCCOMPAT
55
enum ENUM1; // expected-warning {{forward references to 'enum' types are a Microsoft extension}}
@@ -35,3 +35,15 @@ size_t x;
3535
#else
3636
size_t x; // expected-error {{unknown type name 'size_t'}}
3737
#endif
38+
39+
/* Microsoft allows inline, __inline, and __forceinline to appear on a typedef
40+
of a function type; this is used in their system headers such as ufxclient.h
41+
See GitHub #124869 for more details.
42+
*/
43+
typedef int inline Foo1(int); // compat-warning {{'inline' can only appear on functions}} \
44+
ext-error {{'inline' can only appear on functions}}
45+
typedef int __inline Foo2(int); // compat-warning {{'inline' can only appear on functions}} \
46+
ext-error {{'inline' can only appear on functions}}
47+
typedef int __forceinline Foo(int); // compat-warning {{'inline' can only appear on functions}} \
48+
ext-error {{'inline' can only appear on functions}} \
49+
expected-warning {{'__forceinline' attribute only applies to functions and statements}}

clang/test/Sema/MicrosoftCompatibility.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,10 @@ struct cls {
88
};
99

1010
char * cls::* __uptr wrong2 = &cls::m; // expected-error {{'__uptr' attribute cannot be used with pointers to members}}
11+
12+
// Microsoft allows inline, __inline, and __forceinline to appear on a typedef
13+
// of a function type, but only in C. See GitHub #124869 for more details.
14+
typedef int inline Foo1(int); // expected-error {{'inline' can only appear on functions}}
15+
typedef int __inline Foo2(int); // expected-error {{'inline' can only appear on functions}}
16+
typedef int __forceinline Foo(int); // expected-error {{'inline' can only appear on functions}} \
17+
expected-warning {{'__forceinline' attribute only applies to functions and statements}}

0 commit comments

Comments
 (0)