phosek updated this revision to Diff 213170.
phosek edited the summary of this revision.
phosek added a comment.
Herald added a subscriber: cryptoad.
I've updated the change and renamed the flag to `-fsanitize-no-runtime` 
although I'm not sure if it's necessarily better. I was thinking that ideal 
interface might be `-fsanitize-runtime=(none|minimal|shared|static)` which 
could also replace `-fshared-libsan` and `-fstatic-libsan`, but it'd be a 
breaking change so we might have to keep the existing flag and maybe print a 
deprecation warning. WDYT?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D65029/new/

https://reviews.llvm.org/D65029

Files:
  clang/include/clang/Driver/Options.td
  clang/include/clang/Driver/SanitizerArgs.h
  clang/lib/Driver/SanitizerArgs.cpp
  clang/test/Driver/sanitizer-ld.c

Index: clang/test/Driver/sanitizer-ld.c
===================================================================
--- clang/test/Driver/sanitizer-ld.c
+++ clang/test/Driver/sanitizer-ld.c
@@ -28,6 +28,14 @@
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-SHARED-ASAN-LINUX %s
 
+// RUN: %clang -fsanitize=address -fsanitize-no-runtime %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux -fuse-ld=ld \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-ASAN-NO-RUNTIME-LINUX %s
+//
+// CHECK-ASAN-NO-RUNTIME-LINUX-NOT: libclang_rt.asan-x86_64.a"
+
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux -fuse-ld=ld -fsanitize=address \
 // RUN:     -shared-libsan -static-libsan -shared-libasan             \
Index: clang/lib/Driver/SanitizerArgs.cpp
===================================================================
--- clang/lib/Driver/SanitizerArgs.cpp
+++ clang/lib/Driver/SanitizerArgs.cpp
@@ -208,7 +208,7 @@
   // All of these include ubsan.
   if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
       needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
-      (needsScudoRt() && !requiresMinimalRuntime()))
+      (needsScudoRt() && !requiresMinimalRuntime()) || RT == SRT_None)
     return false;
 
   return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) ||
@@ -217,12 +217,12 @@
 
 bool SanitizerArgs::needsCfiRt() const {
   return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
-         CfiCrossDso && !ImplicitCfiRuntime;
+         CfiCrossDso && !ImplicitCfiRuntime && RT != SRT_None;
 }
 
 bool SanitizerArgs::needsCfiDiagRt() const {
   return (Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
-         CfiCrossDso && !ImplicitCfiRuntime;
+         CfiCrossDso && !ImplicitCfiRuntime && RT != SRT_None;
 }
 
 bool SanitizerArgs::requiresPIE() const {
@@ -261,9 +261,21 @@
   SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args);
   SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap;
 
-  MinimalRuntime =
-      Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
-                   options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
+  auto *RuntimeArg = Args.getLastArg(
+      options::OPT_fsanitize_no_runtime, options::OPT_fno_sanitize_no_runtime,
+      options::OPT_fsanitize_minimal_runtime, options::OPT_fno_sanitize_minimal_runtime);
+
+  if (RuntimeArg) {
+    Option O = RuntimeArg->getOption();
+    if (O.matches(options::OPT_fsanitize_no_runtime))
+      RT = SRT_None;
+    if (O.matches(options::OPT_fno_sanitize_no_runtime))
+      RT = SRT_Regular;
+    if (O.matches(options::OPT_fsanitize_minimal_runtime))
+      RT = SRT_Minimal;
+    if (O.matches(options::OPT_fno_sanitize_minimal_runtime))
+      RT = SRT_Regular;
+  }
 
   // The object size sanitizer should not be enabled at -O0.
   Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
@@ -303,7 +315,7 @@
       }
       Add &= ~InvalidTrappingKinds;
 
-      if (MinimalRuntime) {
+      if (requiresMinimalRuntime()) {
         if (SanitizerMask KindsToDiagnose =
                 Add & NotAllowedWithMinimalRuntime & ~DiagnosedKinds) {
           std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
@@ -367,7 +379,7 @@
       // Silently discard any unsupported sanitizers implicitly enabled through
       // group expansion.
       Add &= ~InvalidTrappingKinds;
-      if (MinimalRuntime) {
+      if (requiresMinimalRuntime()) {
         Add &= ~NotAllowedWithMinimalRuntime;
       }
       if (CfiCrossDso)
@@ -640,7 +652,7 @@
   Stats = Args.hasFlag(options::OPT_fsanitize_stats,
                        options::OPT_fno_sanitize_stats, false);
 
-  if (MinimalRuntime) {
+  if (requiresMinimalRuntime()) {
     SanitizerMask IncompatibleMask =
         Kinds & ~setGroupBits(CompatibleWithMinimalRuntime);
     if (IncompatibleMask)
@@ -972,7 +984,9 @@
   if (Stats)
     CmdArgs.push_back("-fsanitize-stats");
 
-  if (MinimalRuntime)
+  if (RT == SRT_None)
+    CmdArgs.push_back("-fsanitize-no-runtime");
+  else if (RT == SRT_Minimal)
     CmdArgs.push_back("-fsanitize-minimal-runtime");
 
   if (AsanFieldPadding)
Index: clang/include/clang/Driver/SanitizerArgs.h
===================================================================
--- clang/include/clang/Driver/SanitizerArgs.h
+++ clang/include/clang/Driver/SanitizerArgs.h
@@ -21,6 +21,17 @@
 class ToolChain;
 
 class SanitizerArgs {
+  enum SanitizerRuntimeKind {
+    /// Don't use any sanitizer runtime.
+    SRT_None,
+
+    /// Use minimal sanitizer runtime.
+    SRT_Minimal,
+
+    /// Regular sanitizer runtime.
+    SRT_Regular,
+  };
+
   SanitizerSet Sanitizers;
   SanitizerSet RecoverableSanitizers;
   SanitizerSet TrapSanitizers;
@@ -48,7 +59,7 @@
   bool TsanMemoryAccess = true;
   bool TsanFuncEntryExit = true;
   bool TsanAtomics = true;
-  bool MinimalRuntime = false;
+  SanitizerRuntimeKind RT = SRT_Regular;
   // True if cross-dso CFI support if provided by the system (i.e. Android).
   bool ImplicitCfiRuntime = false;
 
@@ -58,24 +69,39 @@
 
   bool needsSharedRt() const { return SharedRuntime; }
 
-  bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); }
-  bool needsHwasanRt() const { return Sanitizers.has(SanitizerKind::HWAddress); }
-  bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); }
-  bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); }
-  bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); }
+  bool needsAsanRt() const {
+    return Sanitizers.has(SanitizerKind::Address) && RT != SRT_None;
+  }
+  bool needsHwasanRt() const {
+    return Sanitizers.has(SanitizerKind::HWAddress) && RT != SRT_None;
+  }
+  bool needsTsanRt() const {
+    return Sanitizers.has(SanitizerKind::Thread) && RT != SRT_None;
+  }
+  bool needsMsanRt() const {
+    return Sanitizers.has(SanitizerKind::Memory) && RT != SRT_None;
+  }
+  bool needsFuzzer() const {
+    return Sanitizers.has(SanitizerKind::Fuzzer) && RT != SRT_None;
+  }
   bool needsLsanRt() const {
     return Sanitizers.has(SanitizerKind::Leak) &&
            !Sanitizers.has(SanitizerKind::Address) &&
-           !Sanitizers.has(SanitizerKind::HWAddress);
+           !Sanitizers.has(SanitizerKind::HWAddress) && RT != SRT_None;
   }
   bool needsUbsanRt() const;
-  bool requiresMinimalRuntime() const { return MinimalRuntime; }
-  bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); }
-  bool needsSafeStackRt() const { return SafeStackRuntime; }
+  bool requiresRuntime() const { return RT != SRT_None; }
+  bool requiresMinimalRuntime() const { return RT == SRT_Minimal; }
+  bool needsDfsanRt() const {
+    return Sanitizers.has(SanitizerKind::DataFlow) && RT != SRT_None;
+  }
+  bool needsSafeStackRt() const { return SafeStackRuntime && RT != SRT_None; }
   bool needsCfiRt() const;
   bool needsCfiDiagRt() const;
-  bool needsStatsRt() const { return Stats; }
-  bool needsScudoRt() const { return Sanitizers.has(SanitizerKind::Scudo); }
+  bool needsStatsRt() const { return Stats && RT != SRT_None; }
+  bool needsScudoRt() const {
+    return Sanitizers.has(SanitizerKind::Scudo) && RT != SRT_None;
+  }
 
   bool requiresPIE() const;
   bool needsUnwindTables() const;
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1043,6 +1043,10 @@
                                         Group<f_clang_Group>;
 def fno_sanitize_minimal_runtime : Flag<["-"], "fno-sanitize-minimal-runtime">,
                                         Group<f_clang_Group>;
+def fsanitize_no_runtime : Flag<["-"], "fsanitize-no-runtime">,
+                           Group<f_clang_Group>;
+def fno_sanitize_no_runtime : Flag<["-"], "fno-sanitize-no-runtime">,
+                              Group<f_clang_Group>;
 def fsanitize_link_cxx_runtime : Flag<["-"], "fsanitize-link-c++-runtime">,
                                  Group<f_clang_Group>;
 def fsanitize_cfi_cross_dso : Flag<["-"], "fsanitize-cfi-cross-dso">,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to