zixuw updated this revision to Diff 274212.
zixuw added a comment.
- Refine test cases to check combinations of 'Wundef' and 'Wundef-prefix', and
with/without 'Werror';
- Fix issues with '-Werror=undef' by explicitly looking for the option.
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/DiagnosticGroups.td
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,57 @@
+// 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}}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundef"
+
+#if A // no warning/error
+#endif
+
+#pragma clang diagnostic pop
+
+#if A // #4
+#endif
+// undef-warning@#4 {{'A' is not defined, evaluates to 0}}
+// undef-prefix-warning@#4 {{'A' is not defined, evaluates to 0}}
+// both-warning@#4 {{'A' is not defined, evaluates to 0}}
+// undef-error-error@#4 {{'A' is not defined, evaluates to 0}}
+// undef-prefix-error-error@#4 {{'A' is not defined, evaluates to 0}}
+// both-error-error@#4 {{'A' is not defined, evaluates to 0}}
Index: clang/lib/Lex/PPExpressions.cpp
===================================================================
--- clang/lib/Lex/PPExpressions.cpp
+++ clang/lib/Lex/PPExpressions.cpp
@@ -28,6 +28,7 @@
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
@@ -251,8 +252,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)
- PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
+ if (ValueLive) {
+ const DiagnosticOptions &diagOptions =
+ PP.getDiagnostics().getDiagnosticOptions();
+ const StringRef IdentifierName = II->getName();
+ // Check whether "-Werror=undef" is present.
+ // "-Werror=undef" implies "-Wundef" but does not add an empty
+ // string to UndefPrefixes as an explicit "-Wundef" does.
+ // This check ensures that "-Werror=undef" emits errors for all
+ // undefined macros.
+ const bool hasWerrorEQundef =
+ llvm::is_contained(diagOptions.Warnings, "error=undef");
+ if (hasWerrorEQundef ||
+ llvm::any_of(diagOptions.UndefPrefixes,
+ [&IdentifierName](const std::string &Prefix) {
+ return IdentifierName.startswith(Prefix);
+ }))
+ PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << 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,16 @@
}
Opts.MessageLength =
getLastArgIntValue(Args, OPT_fmessage_length_EQ, 0, Diags);
+
+ for (const auto *A : Args.filtered(OPT_Wundef_prefix_EQ)) {
+ SmallVector<StringRef, 2> Prefixes;
+ // Keep empty strings to allow '-Wundef' (aliased to '-Wundef-prefix=""')
+ // to generate diagnostics for all undefined macros.
+ StringRef{A->getValue()}.split(Prefixes, ",");
+ for (const auto &P : Prefixes)
+ Opts.UndefPrefixes.push_back(P.str());
+ }
+
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,14 @@
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 : Joined<["-"], "Wundef-prefix=">, Group<W_value_Group>,
+ Flags<[CC1Option, CoreOption]>, MetaVarName<"<arg>">,
+ HelpText<"Enable warnings for undefined macros with a prefix in the comma separated list <arg>">;
+// Rely on the implementation that a Flag alias for a Joined option is provided a default argument
+// of an empty string (""). So we have -Wundef => -Wundef-prefix=""
+def Wundef: Flag<["-"], "Wundef">, Group<W_Group>, Flags<[CC1Option, CoreOption]>,
+ Alias<Wundef_prefix_EQ>,
+ HelpText<"Aliased to '-Wundef-prefix=\"\"', enable warnings for undefined macros">;
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
@@ -311,7 +311,7 @@
InGroup<DiagGroup<"unused-macros">>;
def warn_pp_undef_identifier : Warning<
"%0 is not defined, evaluates to 0">,
- InGroup<DiagGroup<"undef">>, DefaultIgnore;
+ InGroup<Undefined>, DefaultIgnore;
def warn_pp_ambiguous_macro : Warning<
"ambiguous expansion of macro %0">, InGroup<AmbiguousMacro>;
def note_pp_ambiguous_macro_chosen : Note<
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -105,6 +105,8 @@
def FrameAddress : DiagGroup<"frame-address">;
def DoublePromotion : DiagGroup<"double-promotion">;
def EnumTooLarge : DiagGroup<"enum-too-large">;
+def Undefined : DiagGroup<"undef">;
+def UndefinedPrefix : DiagGroup<"undef-prefix", [Undefined]>;
def UnsupportedNan : DiagGroup<"unsupported-nan">;
def UnsupportedAbs : DiagGroup<"unsupported-abs">;
def UnsupportedCB : DiagGroup<"unsupported-cb">;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits