aaron.ballman created this revision. aaron.ballman added reviewers: rsmith, jyknight, joerg. Herald added a subscriber: jfb.
The `ATOMIC_VAR_INIT` was deprecated in C17 (C17 7.31.8p2), largely because it is fundamentally broken. It has already been proposed to be removed from C2x (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2390.pdf). There is no replacement for the macro because the macro is unnecessary for implementations to get initialization correct (plain assignment suffices). This patch adds a diagnostic when expanding the `ATOMIC_VAR_INIT` macro that comes from stdatomic.h in all C modes. This will help users to recognize that use of this macro is strongly discouraged. https://reviews.llvm.org/D67023 Files: include/clang/Basic/DiagnosticLexKinds.td lib/Lex/PPMacroExpansion.cpp test/Preprocessor/Inputs/atomic_var_init/stdatomic.h test/Preprocessor/atomic_var_init.c Index: test/Preprocessor/atomic_var_init.c =================================================================== --- test/Preprocessor/atomic_var_init.c +++ test/Preprocessor/atomic_var_init.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -Wdeprecated -isystem Inputs/atomic_var_init + +// Do not diagnose if the macro is not defined in stdatomic.h because it could +// be a user-defined macro instead then. +#define ATOMIC_VAR_INIT(x) (x) +_Atomic int a = ATOMIC_VAR_INIT(12); +#undef ATOMIC_VAR_INIT + +// Diagnose use of the macro from stdatomic.h +#include <stdatomic.h> +_Atomic int i = ATOMIC_VAR_INIT(12); // expected-warning {{'ATOMIC_VAR_INIT' is deprecated}} + +#define FOO(x) ATOMIC_VAR_INIT(x) +_Atomic int j = FOO(12); // expected-warning {{'ATOMIC_VAR_INIT' is deprecated}} + +// Do not diagnose use in conditional inclusion directives. +#ifdef ATOMIC_VAR_INIT +#elif defined(ATOMIC_VAR_INIT) +#endif + Index: test/Preprocessor/Inputs/atomic_var_init/stdatomic.h =================================================================== --- test/Preprocessor/Inputs/atomic_var_init/stdatomic.h +++ test/Preprocessor/Inputs/atomic_var_init/stdatomic.h @@ -0,0 +1 @@ +#define ATOMIC_VAR_INIT(x) (x) Index: lib/Lex/PPMacroExpansion.cpp =================================================================== --- lib/Lex/PPMacroExpansion.cpp +++ lib/Lex/PPMacroExpansion.cpp @@ -513,6 +513,18 @@ // Notice that this macro has been used. markMacroAsUsed(MI); + // C17 7.31.8p2 + // If the macro is named ATOMIC_VAR_INIT and it came from the stdatomic.h + // header file, diagnose it as being deprecated. This macro does not exist + // in C++, so do not trigger a deprecation warning in that language mode. + if (!getLangOpts().CPlusPlus && + Identifier.getIdentifierInfo()->isStr("ATOMIC_VAR_INIT") && + llvm::sys::path::filename(getSourceManager().getFilename( + M.getLocalDirective()->getLocation())) == "stdatomic.h") { + Diag(Identifier, diag::warn_pp_macro_deprecated) + << Identifier.getIdentifierInfo(); + } + // Remember where the token is expanded. SourceLocation ExpandLoc = Identifier.getLocation(); SourceRange ExpansionRange(ExpandLoc, ExpansionEnd); Index: include/clang/Basic/DiagnosticLexKinds.td =================================================================== --- include/clang/Basic/DiagnosticLexKinds.td +++ include/clang/Basic/DiagnosticLexKinds.td @@ -326,6 +326,8 @@ def warn_pp_objc_macro_redef_ignored : Warning< "ignoring redefinition of Objective-C qualifier macro">, InGroup<DiagGroup<"objc-macro-redefinition">>; +def warn_pp_macro_deprecated : Warning<"%0 is deprecated">, + InGroup<Deprecated>; def pp_invalid_string_literal : Warning< "invalid string literal, ignoring final '\\'">;
Index: test/Preprocessor/atomic_var_init.c =================================================================== --- test/Preprocessor/atomic_var_init.c +++ test/Preprocessor/atomic_var_init.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -Wdeprecated -isystem Inputs/atomic_var_init + +// Do not diagnose if the macro is not defined in stdatomic.h because it could +// be a user-defined macro instead then. +#define ATOMIC_VAR_INIT(x) (x) +_Atomic int a = ATOMIC_VAR_INIT(12); +#undef ATOMIC_VAR_INIT + +// Diagnose use of the macro from stdatomic.h +#include <stdatomic.h> +_Atomic int i = ATOMIC_VAR_INIT(12); // expected-warning {{'ATOMIC_VAR_INIT' is deprecated}} + +#define FOO(x) ATOMIC_VAR_INIT(x) +_Atomic int j = FOO(12); // expected-warning {{'ATOMIC_VAR_INIT' is deprecated}} + +// Do not diagnose use in conditional inclusion directives. +#ifdef ATOMIC_VAR_INIT +#elif defined(ATOMIC_VAR_INIT) +#endif + Index: test/Preprocessor/Inputs/atomic_var_init/stdatomic.h =================================================================== --- test/Preprocessor/Inputs/atomic_var_init/stdatomic.h +++ test/Preprocessor/Inputs/atomic_var_init/stdatomic.h @@ -0,0 +1 @@ +#define ATOMIC_VAR_INIT(x) (x) Index: lib/Lex/PPMacroExpansion.cpp =================================================================== --- lib/Lex/PPMacroExpansion.cpp +++ lib/Lex/PPMacroExpansion.cpp @@ -513,6 +513,18 @@ // Notice that this macro has been used. markMacroAsUsed(MI); + // C17 7.31.8p2 + // If the macro is named ATOMIC_VAR_INIT and it came from the stdatomic.h + // header file, diagnose it as being deprecated. This macro does not exist + // in C++, so do not trigger a deprecation warning in that language mode. + if (!getLangOpts().CPlusPlus && + Identifier.getIdentifierInfo()->isStr("ATOMIC_VAR_INIT") && + llvm::sys::path::filename(getSourceManager().getFilename( + M.getLocalDirective()->getLocation())) == "stdatomic.h") { + Diag(Identifier, diag::warn_pp_macro_deprecated) + << Identifier.getIdentifierInfo(); + } + // Remember where the token is expanded. SourceLocation ExpandLoc = Identifier.getLocation(); SourceRange ExpansionRange(ExpandLoc, ExpansionEnd); Index: include/clang/Basic/DiagnosticLexKinds.td =================================================================== --- include/clang/Basic/DiagnosticLexKinds.td +++ include/clang/Basic/DiagnosticLexKinds.td @@ -326,6 +326,8 @@ def warn_pp_objc_macro_redef_ignored : Warning< "ignoring redefinition of Objective-C qualifier macro">, InGroup<DiagGroup<"objc-macro-redefinition">>; +def warn_pp_macro_deprecated : Warning<"%0 is deprecated">, + InGroup<Deprecated>; def pp_invalid_string_literal : Warning< "invalid string literal, ignoring final '\\'">;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits