zixuw updated this revision to Diff 274276. zixuw added a comment. Abort the design of making 'Wundef' an alias to 'Wundef-prefix' because it depends on the alias expansion to work, which adds an empty string to 'UndefPrefixes' to do the trick. However, any other way to enable 'Wundef', for example, via 'Werror=undef' or '#pragma clang diagnostic', will not work and cannot be handled easily.
Instead, just suppress 'Wundef-prefix' when 'Wundef' is enabled. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D80751/new/ https://reviews.llvm.org/D80751 Files: clang/include/clang/Basic/DiagnosticLexKinds.td clang/include/clang/Basic/DiagnosticOptions.h clang/include/clang/Driver/Options.td clang/lib/Frontend/CompilerInvocation.cpp clang/lib/Lex/PPExpressions.cpp clang/test/Preprocessor/warn-macro-undef.c
Index: clang/test/Preprocessor/warn-macro-undef.c =================================================================== --- /dev/null +++ clang/test/Preprocessor/warn-macro-undef.c @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 %s -Eonly -Wundef -verify=undef +// RUN: %clang_cc1 %s -Eonly -Wundef-prefix=A,BC -verify=undef-prefix +// RUN: %clang_cc1 %s -Eonly -Wundef -Wundef-prefix=A,BC -verify=both +// RUN: %clang_cc1 %s -Eonly -Werror=undef -verify=undef-error +// RUN: %clang_cc1 %s -Eonly -Werror=undef-prefix -Wundef-prefix=A,BC -verify=undef-prefix-error +// RUN: %clang_cc1 %s -Eonly -Werror=undef -Wundef-prefix=A,BC -verify=both-error + +extern int x; + +#if AB // #1 +#endif +// undef-warning@#1 {{'AB' is not defined, evaluates to 0}} +// undef-prefix-warning@#1 {{'AB' is not defined, evaluates to 0}} +// both-warning@#1 {{'AB' is not defined, evaluates to 0}} +// undef-error-error@#1 {{'AB' is not defined, evaluates to 0}} +// undef-prefix-error-error@#1 {{'AB' is not defined, evaluates to 0}} +// both-error-error@#1 {{'AB' is not defined, evaluates to 0}} + +#if B // #2 +#endif +// undef-warning@#2 {{'B' is not defined, evaluates to 0}} +// no warning for undef-prefix +// both-warning@#2 {{'B' is not defined, evaluates to 0}} +// undef-error-error@#2 {{'B' is not defined, evaluates to 0}} +// no error for undef-prefix +// both-error-error@#2 {{'B' is not defined, evaluates to 0}} + +#define BC 0 +#if BC // no warning/error +#endif + +#undef BC +#if BC // #3 +#endif +// undef-warning@#3 {{'BC' is not defined, evaluates to 0}} +// undef-prefix-warning@#3 {{'BC' is not defined, evaluates to 0}} +// both-warning@#3 {{'BC' is not defined, evaluates to 0}} +// undef-error-error@#3 {{'BC' is not defined, evaluates to 0}} +// undef-prefix-error-error@#3 {{'BC' is not defined, evaluates to 0}} +// both-error-error@#3 {{'BC' is not defined, evaluates to 0}} + +// Test that #pragma-enabled 'Wundef' can override 'Wundef-prefix' +#pragma clang diagnostic error "-Wundef" + +#if C // #4 +#endif +// undef-error@#4 {{'C' is not defined, evaluates to 0}} +// undef-prefix-error@#4 {{'C' is not defined, evaluates to 0}} +// both-error@#4 {{'C' is not defined, evaluates to 0}} +// undef-error-error@#4 {{'C' is not defined, evaluates to 0}} +// undef-prefix-error-error@#4 {{'C' is not defined, evaluates to 0}} +// both-error-error@#4 {{'C' is not defined, evaluates to 0}} Index: clang/lib/Lex/PPExpressions.cpp =================================================================== --- clang/lib/Lex/PPExpressions.cpp +++ clang/lib/Lex/PPExpressions.cpp @@ -15,7 +15,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/Lex/Preprocessor.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" @@ -26,9 +25,12 @@ #include "clang/Lex/LiteralSupport.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" #include "clang/Lex/Token.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SaveAndRestore.h" @@ -251,8 +253,24 @@ // If this identifier isn't 'defined' or one of the special // preprocessor keywords and it wasn't macro expanded, it turns // into a simple 0 - if (ValueLive) + if (ValueLive) { PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II; + + const DiagnosticsEngine &DiagEngine = PP.getDiagnostics(); + // If 'Wundef' is enabled, do not emit 'undef-prefix' diagnostics. + if (DiagEngine.isIgnored(diag::warn_pp_undef_identifier, + PeekTok.getLocation())) { + const std::vector<std::string> UndefPrefixes = + DiagEngine.getDiagnosticOptions().UndefPrefixes; + const StringRef IdentifierName = II->getName(); + if (llvm::any_of(UndefPrefixes, + [&IdentifierName](const std::string &Prefix) { + return IdentifierName.startswith(Prefix); + })) + PP.Diag(PeekTok, diag::warn_pp_undef_prefix) + << AddFlagValue{llvm::join(UndefPrefixes, ",")} << II; + } + } Result.Val = 0; Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0. Result.setIdentifier(II); Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -1688,6 +1688,9 @@ } Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length_EQ, 0, Diags); + + Opts.UndefPrefixes = Args.getAllArgValues(OPT_Wundef_prefix_EQ); + addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings); addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks); Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -483,6 +483,9 @@ def Wp_COMMA : CommaJoined<["-"], "Wp,">, HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">, MetaVarName<"<arg>">, Group<Preprocessor_Group>; +def Wundef_prefix_EQ : CommaJoined<["-"], "Wundef-prefix=">, Group<W_value_Group>, + Flags<[CC1Option, CoreOption, HelpHidden]>, MetaVarName<"<arg>">, + HelpText<"Enable warnings for undefined macros with a prefix in the comma separated list <arg>">; def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>; def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>; def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption]>, Index: clang/include/clang/Basic/DiagnosticOptions.h =================================================================== --- clang/include/clang/Basic/DiagnosticOptions.h +++ clang/include/clang/Basic/DiagnosticOptions.h @@ -98,6 +98,10 @@ /// prefixes removed. std::vector<std::string> Warnings; + /// The list of prefixes from -Wundef-prefix=... used to generate warnings + /// for undefined macros. + std::vector<std::string> UndefPrefixes; + /// The list of -R... options used to alter the diagnostic mappings, with the /// prefixes removed. std::vector<std::string> Remarks; Index: clang/include/clang/Basic/DiagnosticLexKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticLexKinds.td +++ clang/include/clang/Basic/DiagnosticLexKinds.td @@ -312,6 +312,9 @@ def warn_pp_undef_identifier : Warning< "%0 is not defined, evaluates to 0">, InGroup<DiagGroup<"undef">>, DefaultIgnore; +def warn_pp_undef_prefix : Warning< + "%0 is not defined, evaluates to 0">, + InGroup<DiagGroup<"undef-prefix">>, DefaultIgnore; def warn_pp_ambiguous_macro : Warning< "ambiguous expansion of macro %0">, InGroup<AmbiguousMacro>; def note_pp_ambiguous_macro_chosen : Note<
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits