Index: clang/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticDriverKinds.td +++ clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -544,4 +544,9 @@ def err_cc1_round_trip_fail_then_ok : Error<"Original arguments parse failed, then succeeded in round-trip">; def err_cc1_round_trip_ok_then_fail : Error<"Generated arguments parse failed in round-trip">; def err_cc1_round_trip_mismatch : Error<"Generated arguments do not match in round-trip">; + +def warn_drv_fsanitize_trap_ignored : Warning< + "-fsanitize-trap used without -fsanitize is ignored">; +def warn_drv_fsanitize_recover_ignored : Warning< + "-fsanitize-recover used without -fsanitize is ignored">; } Index: clang/lib/Driver/SanitizerArgs.cpp =================================================================== --- clang/lib/Driver/SanitizerArgs.cpp +++ clang/lib/Driver/SanitizerArgs.cpp @@ -205,8 +205,13 @@ return Kinds; } -static SanitizerMask parseSanitizeTrapArgs(const Driver &D, - const llvm::opt::ArgList &Args) { +struct ParsedSanitizeTrapOpts { + SanitizerMask PrunedTrapKinds; + SanitizerMask NoTrapKinds; +}; + +static ParsedSanitizeTrapOpts +parseSanitizeTrapArgs(const Driver &D, const llvm::opt::ArgList &Args) { SanitizerMask TrapRemove; // During the loop below, the accumulated set of // sanitizers disabled by the current sanitizer // argument or any argument after it. @@ -233,10 +238,7 @@ } } - // Apply default trapping behavior. - TrappingKinds |= TrappingDefault & ~TrapRemove; - - return TrappingKinds; + return ParsedSanitizeTrapOpts{TrappingKinds, TrapRemove}; } bool SanitizerArgs::needsFuzzerInterceptors() const { @@ -297,7 +299,11 @@ ToolChain::RTTIMode RTTIMode = TC.getRTTIMode(); const Driver &D = TC.getDriver(); - SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args); + const ParsedSanitizeTrapOpts ParsedKind = parseSanitizeTrapArgs(D, Args); + // Apply default trapping behavior. + SanitizerMask TrappingKinds = + ParsedKind.PrunedTrapKinds | (TrappingDefault & ~ParsedKind.NoTrapKinds); + SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap; MinimalRuntime = @@ -482,6 +488,9 @@ Kinds |= Default; + if (ParsedKind.PrunedTrapKinds && !Kinds) + D.Diag(diag::warn_drv_fsanitize_trap_ignored); + // We disable the vptr sanitizer if it was enabled by group expansion but RTTI // is disabled. if ((Kinds & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) { @@ -544,6 +553,7 @@ SanitizerMask RecoverableKinds = RecoverableByDefault | AlwaysRecoverable; SanitizerMask DiagnosedUnrecoverableKinds; SanitizerMask DiagnosedAlwaysRecoverableKinds; + bool AnyExplicitRecoverableKind = false; for (const auto *Arg : Args) { if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) { SanitizerMask Add = parseArgValues(D, Arg, true); @@ -558,6 +568,7 @@ DiagnosedUnrecoverableKinds |= KindsToDiagnose; } RecoverableKinds |= expandSanitizerGroups(Add); + AnyExplicitRecoverableKind = true; Arg->claim(); } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) { SanitizerMask Remove = parseArgValues(D, Arg, true); @@ -575,6 +586,10 @@ Arg->claim(); } } + + if (AnyExplicitRecoverableKind && !Kinds) + D.Diag(diag::warn_drv_fsanitize_recover_ignored); + RecoverableKinds &= Kinds; RecoverableKinds &= ~Unrecoverable; Index: clang/test/Driver/fsanitize-recover-ignored.c =================================================================== --- /dev/null +++ clang/test/Driver/fsanitize-recover-ignored.c @@ -0,0 +1,5 @@ +// RUN: %clang -fsanitize-recover=integer %s -### 2>&1 | FileCheck %s +// RUN: %clang -fsanitize-recover=shift-base %s -### 2>&1 | FileCheck %s +// RUN: %clang -fsanitize-recover=memory %s -### 2>&1 | FileCheck %s + +// CHECK: warning: -fsanitize-recover used without -fsanitize is ignored Index: clang/test/Driver/fsanitize-trap-ignored.c =================================================================== --- /dev/null +++ clang/test/Driver/fsanitize-trap-ignored.c @@ -0,0 +1,13 @@ +// RUN: %clang -fsanitize-trap=integer %s -### 2>&1 | FileCheck %s +// RUN: %clang -fsanitize-trap=shift-base %s -### 2>&1 | FileCheck %s +// RUN: %clang -fsanitize-trap=memory %s -### 2>&1 | FileCheck %s + +// RUN: %clang -fno-sanitize-trap=shift-base -fsanitize-trap=shift-base %s -### 2>&1 | FileCheck %s +// RUN: %clang -fsanitize-trap=shift-base -fno-sanitize-trap=shift-base %s -### 2>&1 | FileCheck %s -check-prefixes=NO + +// RUN: %clang -fsanitize-trap=shift -fno-sanitize-trap=shift-base %s -### 2>&1 | FileCheck %s + +// RUN: %clang -fsanitize-trap=shift-base -fno-sanitize-trap=shift %s -### 2>&1 | FileCheck %s -check-prefixes=NO + +// CHECK: warning: -fsanitize-trap used without -fsanitize is ignored +// NO-NOT: warning: -fsanitize-trap used without -fsanitize is ignored