Skip to content

Commit 2837557

Browse files
Fznamznoncor3ntin
andauthored
[win][clang] Do not inject static_assert macro definition (#147030)
In ms-compatibility mode we inject static_assert macro definition if assert macro is defined. This is done by 8da0903 for the sake of better diagnosing, in particular to emit a compatibility warning when static_assert keyword is used without inclusion of <assert.h>. Unfortunately it doesn't do a good job in c99 mode adding that macro unexpectedly for the users, so this patch removes macro injection and the diagnostics. --------- Co-authored-by: Corentin Jabot <corentinjabot@gmail.com>
1 parent 6d14483 commit 2837557

File tree

8 files changed

+26
-46
lines changed

8 files changed

+26
-46
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,11 @@ Bug Fixes in This Version
756756
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
757757
- Fixed a crash when a malformed using declaration appears in a ``constexpr`` function. (#GH144264)
758758
- Fixed a bug when use unicode character name in macro concatenation. (#GH145240)
759+
- Clang doesn't erroneously inject a ``static_assert`` macro in ms-compatibility and
760+
-std=c99 mode. This resulted in deletion of ``-W/Wno-microsoft-static-assert``
761+
flag and diagnostic because the macro injection was used to emit this warning.
762+
Unfortunately there is no other good way to diagnose usage of ``static_assert``
763+
macro without inclusion of ``<assert.h>``.
759764

760765
Bug Fixes to Compiler Builtins
761766
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,7 +1450,6 @@ def MicrosoftAnonTag : DiagGroup<"microsoft-anon-tag">;
14501450
def MicrosoftCommentPaste : DiagGroup<"microsoft-comment-paste">;
14511451
def MicrosoftEndOfFile : DiagGroup<"microsoft-end-of-file">;
14521452
def MicrosoftInaccessibleBase : DiagGroup<"microsoft-inaccessible-base">;
1453-
def MicrosoftStaticAssert : DiagGroup<"microsoft-static-assert">;
14541453
def MicrosoftInitFromPredefined : DiagGroup<"microsoft-init-from-predefined">;
14551454
def MicrosoftStringLiteralFromPredefined : DiagGroup<
14561455
"microsoft-string-literal-from-predefined">;
@@ -1472,7 +1471,7 @@ def Microsoft : DiagGroup<"microsoft",
14721471
MicrosoftRedeclareStatic, MicrosoftEnumForwardReference, MicrosoftGoto,
14731472
MicrosoftFlexibleArray, MicrosoftExtraQualification, MicrosoftCast,
14741473
MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag,
1475-
MicrosoftCommentPaste, MicrosoftEndOfFile, MicrosoftStaticAssert,
1474+
MicrosoftCommentPaste, MicrosoftEndOfFile,
14761475
MicrosoftInitFromPredefined, MicrosoftStringLiteralFromPredefined,
14771476
MicrosoftInconsistentDllImport, MicrosoftInlineOnNonFunction]>;
14781477

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -474,9 +474,6 @@ def err_bool_redeclaration : Error<
474474
def warn_cxx98_compat_static_assert : Warning<
475475
"'static_assert' declarations are incompatible with C++98">,
476476
InGroup<CXX98Compat>, DefaultIgnore;
477-
def ext_ms_static_assert : ExtWarn<
478-
"use of 'static_assert' without inclusion of <assert.h> is a Microsoft "
479-
"extension">, InGroup<MicrosoftStaticAssert>;
480477
def ext_cxx_static_assert_no_message : ExtWarn<
481478
"'static_assert' with no message is a C++17 extension">, InGroup<CXX17>;
482479
def ext_c_static_assert_no_message : ExtWarn<

clang/lib/Lex/PPDirectives.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3304,23 +3304,6 @@ void Preprocessor::HandleDefineDirective(
33043304
// If the callbacks want to know, tell them about the macro definition.
33053305
if (Callbacks)
33063306
Callbacks->MacroDefined(MacroNameTok, MD);
3307-
3308-
// If we're in MS compatibility mode and the macro being defined is the
3309-
// assert macro, implicitly add a macro definition for static_assert to work
3310-
// around their broken assert.h header file in C. Only do so if there isn't
3311-
// already a static_assert macro defined.
3312-
if (!getLangOpts().CPlusPlus && getLangOpts().MSVCCompat &&
3313-
MacroNameTok.getIdentifierInfo()->isStr("assert") &&
3314-
!isMacroDefined("static_assert")) {
3315-
MacroInfo *MI = AllocateMacroInfo(SourceLocation());
3316-
3317-
Token Tok;
3318-
Tok.startToken();
3319-
Tok.setKind(tok::kw__Static_assert);
3320-
Tok.setIdentifierInfo(getIdentifierInfo("_Static_assert"));
3321-
MI->setTokens({Tok}, BP);
3322-
(void)appendDefMacroDirective(getIdentifierInfo("static_assert"), MI);
3323-
}
33243307
}
33253308

33263309
/// HandleUndefDirective - Implements \#undef.

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -937,9 +937,6 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
937937
if (!getLangOpts().CPlusPlus) {
938938
if (getLangOpts().C23)
939939
Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
940-
else
941-
Diag(Tok, diag::ext_ms_static_assert) << FixItHint::CreateReplacement(
942-
Tok.getLocation(), "_Static_assert");
943940
} else
944941
Diag(Tok, diag::warn_cxx98_compat_static_assert);
945942
}

clang/test/Parser/static_assert.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ static_assert(1, ""); // c17-warning {{'static_assert' is a keyword in C23}} \
2020
// c17-error {{expected ')'}} \
2121
// c17-note {{to match this '('}} \
2222
// c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} \
23-
// c17-ms-warning {{use of 'static_assert' without inclusion of <assert.h> is a Microsoft extension}}
2423
2524
#endif
2625

clang/test/Preprocessor/static_assert.c

Lines changed: 0 additions & 12 deletions
This file was deleted.

clang/test/Sema/static-assert.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %clang_cc1 -std=c11 -Wgnu-folding-constant -fsyntax-only -verify %s
22
// RUN: %clang_cc1 -fms-compatibility -Wgnu-folding-constant -DMS -fsyntax-only -verify=expected,ms %s
3+
// RUN: %clang_cc1 -std=c99 -fms-compatibility -Wgnu-folding-constant -DMS -fsyntax-only -verify=expected,ms %s
34
// RUN: %clang_cc1 -std=c99 -pedantic -Wgnu-folding-constant -fsyntax-only -verify=expected,ext %s
45
// RUN: %clang_cc1 -xc++ -std=c++11 -pedantic -fsyntax-only -verify=expected,ext,cxx %s
56

@@ -13,15 +14,15 @@ _Static_assert(0, "0 is nonzero"); // expected-error {{static assertion failed:
1314
// ext-warning {{'_Static_assert' is a C11 extension}}
1415

1516
#ifdef MS
16-
static_assert(1, "1 is nonzero"); // ms-warning {{use of 'static_assert' without inclusion of <assert.h> is a Microsoft extension}}
17+
static_assert(1, "1 is nonzero");
1718
#endif
1819

1920
void foo(void) {
2021
_Static_assert(1, "1 is nonzero"); // ext-warning {{'_Static_assert' is a C11 extension}}
2122
_Static_assert(0, "0 is nonzero"); // expected-error {{static assertion failed: 0 is nonzero}} \
2223
// ext-warning {{'_Static_assert' is a C11 extension}}
2324
#ifdef MS
24-
static_assert(1, "1 is nonzero"); // ms-warning {{use of 'static_assert' without}}
25+
static_assert(1, "1 is nonzero");
2526
#endif
2627
}
2728

@@ -38,7 +39,7 @@ struct A {
3839
_Static_assert(0, "0 is nonzero"); // expected-error {{static assertion failed: 0 is nonzero}} \
3940
// ext-warning {{'_Static_assert' is a C11 extension}}
4041
#ifdef MS
41-
static_assert(1, "1 is nonzero"); // ms-warning {{use of 'static_assert' without}}
42+
static_assert(1, "1 is nonzero");
4243
#endif
4344
};
4445

@@ -64,16 +65,27 @@ typedef UNION(char, short) U3; // expected-error {{static assertion failed due t
6465
typedef UNION(float, 0.5f) U4; // expected-error {{expected a type}} \
6566
// ext-warning 3 {{'_Static_assert' is a C11 extension}}
6667

67-
// After defining the assert macro in MS-compatibility mode, we should
68-
// no longer warn about including <assert.h> under the assumption the
69-
// user already did that.
68+
// MSVC accepts static_assert in all language modes without including <assert.h>
69+
// and so do we in ms-compatibility mode. Unfortunately, there is no good way
70+
// to diagnose that with a pedantic warning. We'd have to track inclusion of
71+
// <assert.h> which is difficult when modules and PCH are involved. Adding
72+
// implicit definition of the macro causes unexpected results in c99 mode.
7073
#ifdef MS
74+
75+
#if __STDC_VERSION__ < 201112L
76+
#if defined(static_assert)
77+
static_assert(0, "0 is nonzero"); // ok because we should not define static_assert
78+
// macro in c99.
79+
#endif
80+
81+
static_assert(0, "0 is nonzero"); // ms-error {{static assertion failed: 0 is nonzero}}
82+
#endif
83+
7184
#define assert(expr)
7285
static_assert(1, "1 is nonzero"); // ok
7386

74-
// But we should still warn if the user did something bonkers.
7587
#undef static_assert
76-
static_assert(1, "1 is nonzero"); // ms-warning {{use of 'static_assert' without}}
88+
static_assert(1, "1 is nonzero"); // yes, still ok.
7789
#endif
7890

7991
_Static_assert(1 , "") // expected-error {{expected ';' after '_Static_assert'}} \

0 commit comments

Comments
 (0)