[clang] [sanitizer] Refactor -f(no-)?sanitize-recover parsing (PR #119819)
Thurston Dang via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 17 10:52:53 PST 2024
================
@@ -247,48 +247,72 @@ static SanitizerMask setGroupBits(SanitizerMask Kinds) {
return Kinds;
}
-// Computes the sanitizer mask based on the default plus opt-in (if supported)
-// minus opt-out.
+// Computes the sanitizer mask as:
+// Default + AlwaysIn + Arguments - AlwaysOut
+// with arguments parsed from left to right.
+//
+// Error messages are optionally printed if the AlwaysIn or AlwaysOut
+// invariants are violated.
static SanitizerMask
parseSanitizeArgs(const Driver &D, const llvm::opt::ArgList &Args,
- bool DiagnoseErrors, SanitizerMask Supported,
- SanitizerMask Default, int OptInID, int OptOutID) {
- SanitizerMask Remove; // During the loop below, the accumulated set of
- // sanitizers disabled by the current sanitizer
- // argument or any argument after it.
- SanitizerMask Kinds;
- SanitizerMask SupportedWithGroups = setGroupBits(Supported);
-
- for (const llvm::opt::Arg *Arg : llvm::reverse(Args)) {
+ bool DiagnoseErrors, SanitizerMask Default,
+ SanitizerMask AlwaysIn, SanitizerMask AlwaysOut, int OptInID,
+ int OptOutID) {
+
+ SanitizerMask Output = Default | AlwaysIn;
+ // Keep track of which violations we have already reported, to avoid
+ // duplicate error messages.
+ SanitizerMask DiagnosedAlwaysInViolations;
+ SanitizerMask DiagnosedAlwaysOutViolations;
+ for (const auto *Arg : Args) {
if (Arg->getOption().matches(OptInID)) {
- Arg->claim();
- SanitizerMask Add = parseArgValues(D, Arg, true);
- Add &= ~Remove;
- SanitizerMask InvalidValues = Add & ~SupportedWithGroups;
- if (InvalidValues && DiagnoseErrors) {
- SanitizerSet S;
- S.Mask = InvalidValues;
- D.Diag(diag::err_drv_unsupported_option_argument)
- << Arg->getSpelling() << toString(S);
+ SanitizerMask Add = parseArgValues(D, Arg, DiagnoseErrors);
+ // Report error if user explicitly tries to opt-in to an always-out
+ // sanitizer.
+ if (SanitizerMask KindsToDiagnose =
+ Add & AlwaysOut & ~DiagnosedAlwaysOutViolations) {
+ if (DiagnoseErrors) {
+ SanitizerSet SetToDiagnose;
+ SetToDiagnose.Mask |= KindsToDiagnose;
+ D.Diag(diag::err_drv_unsupported_option_argument)
+ << Arg->getSpelling() << toString(SetToDiagnose);
+ DiagnosedAlwaysOutViolations |= KindsToDiagnose;
+ }
}
- Kinds |= expandSanitizerGroups(Add) & ~Remove;
+ Output |= expandSanitizerGroups(Add);
+ Arg->claim();
} else if (Arg->getOption().matches(OptOutID)) {
+ SanitizerMask Remove = parseArgValues(D, Arg, DiagnoseErrors);
+ // Report error if user explicitly tries to opt-out of an always-in
+ // sanitizer.
+ if (SanitizerMask KindsToDiagnose =
+ Remove & AlwaysIn & ~DiagnosedAlwaysInViolations) {
+ if (DiagnoseErrors) {
+ SanitizerSet SetToDiagnose;
+ SetToDiagnose.Mask |= KindsToDiagnose;
+ D.Diag(diag::err_drv_unsupported_option_argument)
+ << Arg->getSpelling() << toString(SetToDiagnose);
+ DiagnosedAlwaysInViolations |= KindsToDiagnose;
+ }
+ }
+ Output &= ~expandSanitizerGroups(Remove);
Arg->claim();
- Remove |= expandSanitizerGroups(parseArgValues(D, Arg, DiagnoseErrors));
}
}
- // Apply default behavior.
- Kinds |= Default & ~Remove;
+ Output &= ~AlwaysOut;
----------------
thurstond wrote:
Done
https://github.com/llvm/llvm-project/pull/119819
More information about the cfe-commits
mailing list