https://github.com/Fznamznon updated https://github.com/llvm/llvm-project/pull/147030
>From 3060e6f416ea62bdf62470e6636278d736cc49d0 Mon Sep 17 00:00:00 2001 From: "Podchishchaeva, Mariya" <mariya.podchishcha...@intel.com> Date: Fri, 4 Jul 2025 02:50:38 -0700 Subject: [PATCH 1/3] [win][clang] Do not inject static_assert macro definition In ms-compatibility mode we inject static_assert macro definition if assert macro is defined. This is done by 8da090381d567d0ec555840f6b2a651d2997e4b3 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 disagnostic. --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Lex/PPDirectives.cpp | 17 --------------- clang/lib/Parse/ParseDeclCXX.cpp | 3 --- clang/test/Parser/static_assert.c | 1 - clang/test/Preprocessor/static_assert.c | 12 ----------- clang/test/Sema/static-assert.c | 28 ++++++++++++++++++------- 6 files changed, 22 insertions(+), 41 deletions(-) delete mode 100644 clang/test/Preprocessor/static_assert.c diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 023f8ff7951d3..b66b2c0b7b707 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -750,6 +750,8 @@ Bug Fixes in This Version - Fixed an infinite recursion when checking constexpr destructors. (#GH141789) - Fixed a crash when a malformed using declaration appears in a ``constexpr`` function. (#GH144264) - Fixed a bug when use unicode character name in macro concatenation. (#GH145240) +- Clang doesn't erroneously inject static_assert macro in ms-compatibility and + -std=c99 mode. Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index e6da19d24f1c5..3fa060f7ec1bd 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -3304,23 +3304,6 @@ void Preprocessor::HandleDefineDirective( // If the callbacks want to know, tell them about the macro definition. if (Callbacks) Callbacks->MacroDefined(MacroNameTok, MD); - - // If we're in MS compatibility mode and the macro being defined is the - // assert macro, implicitly add a macro definition for static_assert to work - // around their broken assert.h header file in C. Only do so if there isn't - // already a static_assert macro defined. - if (!getLangOpts().CPlusPlus && getLangOpts().MSVCCompat && - MacroNameTok.getIdentifierInfo()->isStr("assert") && - !isMacroDefined("static_assert")) { - MacroInfo *MI = AllocateMacroInfo(SourceLocation()); - - Token Tok; - Tok.startToken(); - Tok.setKind(tok::kw__Static_assert); - Tok.setIdentifierInfo(getIdentifierInfo("_Static_assert")); - MI->setTokens({Tok}, BP); - (void)appendDefMacroDirective(getIdentifierInfo("static_assert"), MI); - } } /// HandleUndefDirective - Implements \#undef. diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index bd5c28b1992c4..a8832209d32b7 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -937,9 +937,6 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) { if (!getLangOpts().CPlusPlus) { if (getLangOpts().C23) Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName(); - else - Diag(Tok, diag::ext_ms_static_assert) << FixItHint::CreateReplacement( - Tok.getLocation(), "_Static_assert"); } else Diag(Tok, diag::warn_cxx98_compat_static_assert); } diff --git a/clang/test/Parser/static_assert.c b/clang/test/Parser/static_assert.c index e9d7d3f0833f3..1b9b6b676e3e6 100644 --- a/clang/test/Parser/static_assert.c +++ b/clang/test/Parser/static_assert.c @@ -20,7 +20,6 @@ static_assert(1, ""); // c17-warning {{'static_assert' is a keyword in C23}} \ // c17-error {{expected ')'}} \ // c17-note {{to match this '('}} \ // c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} \ - // c17-ms-warning {{use of 'static_assert' without inclusion of <assert.h> is a Microsoft extension}} #endif diff --git a/clang/test/Preprocessor/static_assert.c b/clang/test/Preprocessor/static_assert.c deleted file mode 100644 index 7fa9975e1d468..0000000000000 --- a/clang/test/Preprocessor/static_assert.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -E -dM %s | FileCheck --strict-whitespace --check-prefix=NOMS %s -// RUN: %clang_cc1 -fms-compatibility -E -dM %s | FileCheck --strict-whitespace --check-prefix=MS %s - -// If the assert macro is defined in MS compatibility mode in C, we -// automatically inject a macro definition for static_assert. Test that the -// macro is properly added to the preprocessed output. This allows us to -// diagonse use of the static_assert keyword when <assert.h> has not been -// included while still being able to compile preprocessed code. -#define assert - -MS: #define static_assert _Static_assert -NOMS-NOT: #define static_assert _Static_assert diff --git a/clang/test/Sema/static-assert.c b/clang/test/Sema/static-assert.c index d603bc19bb824..dd83cd7684d2c 100644 --- a/clang/test/Sema/static-assert.c +++ b/clang/test/Sema/static-assert.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -std=c11 -Wgnu-folding-constant -fsyntax-only -verify %s // RUN: %clang_cc1 -fms-compatibility -Wgnu-folding-constant -DMS -fsyntax-only -verify=expected,ms %s +// RUN: %clang_cc1 -std=c99 -fms-compatibility -Wgnu-folding-constant -DMS -fsyntax-only -verify=expected,ms %s // RUN: %clang_cc1 -std=c99 -pedantic -Wgnu-folding-constant -fsyntax-only -verify=expected,ext %s // RUN: %clang_cc1 -xc++ -std=c++11 -pedantic -fsyntax-only -verify=expected,ext,cxx %s @@ -13,7 +14,7 @@ _Static_assert(0, "0 is nonzero"); // expected-error {{static assertion failed: // ext-warning {{'_Static_assert' is a C11 extension}} #ifdef MS -static_assert(1, "1 is nonzero"); // ms-warning {{use of 'static_assert' without inclusion of <assert.h> is a Microsoft extension}} +static_assert(1, "1 is nonzero"); #endif void foo(void) { @@ -21,7 +22,7 @@ void foo(void) { _Static_assert(0, "0 is nonzero"); // expected-error {{static assertion failed: 0 is nonzero}} \ // ext-warning {{'_Static_assert' is a C11 extension}} #ifdef MS - static_assert(1, "1 is nonzero"); // ms-warning {{use of 'static_assert' without}} + static_assert(1, "1 is nonzero"); #endif } @@ -38,7 +39,7 @@ struct A { _Static_assert(0, "0 is nonzero"); // expected-error {{static assertion failed: 0 is nonzero}} \ // ext-warning {{'_Static_assert' is a C11 extension}} #ifdef MS - static_assert(1, "1 is nonzero"); // ms-warning {{use of 'static_assert' without}} + static_assert(1, "1 is nonzero"); #endif }; @@ -64,16 +65,27 @@ typedef UNION(char, short) U3; // expected-error {{static assertion failed due t typedef UNION(float, 0.5f) U4; // expected-error {{expected a type}} \ // ext-warning 3 {{'_Static_assert' is a C11 extension}} -// After defining the assert macro in MS-compatibility mode, we should -// no longer warn about including <assert.h> under the assumption the -// user already did that. +// MSVC accepts static_assert in all language modes without including <assert.h> +// and so do we in ms-compatibility mode. Unfortunately, there is no good way +// to diagnose that with a pedantic warning. We'd have to track inclusion of +// <assert.h> which is difficult when modules and PCH are involved. Adding +// implicit definition of the macro causes unexpected results in c99 mode. #ifdef MS + +#if __STDC_VERSION__ < 201112L +#if defined(static_assert) +static_assert(0, "0 is nonzero"); // ok because we should not define static_assert + // macro in c99. +#endif + +static_assert(0, "0 is nonzero"); // ms-error {{static assertion failed: 0 is nonzero}} +#endif + #define assert(expr) static_assert(1, "1 is nonzero"); // ok -// But we should still warn if the user did something bonkers. #undef static_assert -static_assert(1, "1 is nonzero"); // ms-warning {{use of 'static_assert' without}} +static_assert(1, "1 is nonzero"); // yes, still ok. #endif _Static_assert(1 , "") // expected-error {{expected ';' after '_Static_assert'}} \ >From 6b9dc4a6567dbe1061fa46b02e852cffbea19725 Mon Sep 17 00:00:00 2001 From: "Podchishchaeva, Mariya" <mariya.podchishcha...@intel.com> Date: Fri, 4 Jul 2025 03:00:49 -0700 Subject: [PATCH 2/3] Remove the diag --- clang/include/clang/Basic/DiagnosticGroups.td | 3 +-- clang/include/clang/Basic/DiagnosticParseKinds.td | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 36fa3227fd6a6..0603716942e0e 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1450,7 +1450,6 @@ def MicrosoftAnonTag : DiagGroup<"microsoft-anon-tag">; def MicrosoftCommentPaste : DiagGroup<"microsoft-comment-paste">; def MicrosoftEndOfFile : DiagGroup<"microsoft-end-of-file">; def MicrosoftInaccessibleBase : DiagGroup<"microsoft-inaccessible-base">; -def MicrosoftStaticAssert : DiagGroup<"microsoft-static-assert">; def MicrosoftInitFromPredefined : DiagGroup<"microsoft-init-from-predefined">; def MicrosoftStringLiteralFromPredefined : DiagGroup< "microsoft-string-literal-from-predefined">; @@ -1472,7 +1471,7 @@ def Microsoft : DiagGroup<"microsoft", MicrosoftRedeclareStatic, MicrosoftEnumForwardReference, MicrosoftGoto, MicrosoftFlexibleArray, MicrosoftExtraQualification, MicrosoftCast, MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag, - MicrosoftCommentPaste, MicrosoftEndOfFile, MicrosoftStaticAssert, + MicrosoftCommentPaste, MicrosoftEndOfFile, MicrosoftInitFromPredefined, MicrosoftStringLiteralFromPredefined, MicrosoftInconsistentDllImport, MicrosoftInlineOnNonFunction]>; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 6c30da376dafb..1d86d1f548734 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -474,9 +474,6 @@ def err_bool_redeclaration : Error< def warn_cxx98_compat_static_assert : Warning< "'static_assert' declarations are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; -def ext_ms_static_assert : ExtWarn< - "use of 'static_assert' without inclusion of <assert.h> is a Microsoft " - "extension">, InGroup<MicrosoftStaticAssert>; def ext_cxx_static_assert_no_message : ExtWarn< "'static_assert' with no message is a C++17 extension">, InGroup<CXX17>; def ext_c_static_assert_no_message : ExtWarn< >From 19026544a9c8dd91f8587a1e132ab01770f6f6f2 Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva <mariya.podchishcha...@intel.com> Date: Mon, 7 Jul 2025 10:35:41 +0200 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Corentin Jabot <corentinja...@gmail.com> --- clang/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b66b2c0b7b707..be7f7d202fe02 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -750,7 +750,7 @@ Bug Fixes in This Version - Fixed an infinite recursion when checking constexpr destructors. (#GH141789) - Fixed a crash when a malformed using declaration appears in a ``constexpr`` function. (#GH144264) - Fixed a bug when use unicode character name in macro concatenation. (#GH145240) -- Clang doesn't erroneously inject static_assert macro in ms-compatibility and +- Clang doesn't erroneously inject a ``static_assert`` macro in ms-compatibility and -std=c99 mode. Bug Fixes to Compiler Builtins _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits