pratyai updated this revision to Diff 254418.
pratyai added a comment.

- Switched to Int1Ty.
- Switched Atomic::NonAtomic (same as just dropping the two lines?)
- C++ files were clang-formatted, but arc lint couldn't find clang-format-diff 
before. Now it seems to have formatted the lit tests.
- Will split the patch later (i.e. remove all non-instrumentation stuff from 
this patch, then move flags & compiler-rt tests into two other patches).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D77244

Files:
  clang/docs/SanitizerCoverage.rst
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/CC1Options.td
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/Driver/autocomplete.c
  clang/test/Driver/fsanitize-coverage.c
  
compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp
  llvm/include/llvm/Transforms/Instrumentation.h
  llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
  llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll
  llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll
  llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll
  llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll

Index: llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll
===================================================================
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll
@@ -0,0 +1,14 @@
+; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-pc-guard -sanitizer-coverage-inline-bool-flag -S | FileCheck %s
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=1 -sanitizer-coverage-trace-pc-guard -sanitizer-coverage-inline-bool-flag -S | FileCheck %s
+
+; Module ctors should have stable names across modules, not something like
+; @sancov.module_ctor.3 that may cause duplicate ctors after linked together.
+
+; CHECK: define internal void @sancov.module_ctor_trace_pc_guard() comdat {
+; CHECK: define internal void @sancov.module_ctor_bool_flag() comdat {
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo() {
+  ret void
+}
Index: llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll
===================================================================
--- llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll
+++ llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll
@@ -1,8 +1,10 @@
 ; Test -sanitizer-coverage-pc-table=1
 ; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard       -sanitizer-coverage-pc-table=1 -S | FileCheck %s
 ; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-inline-8bit-counters -sanitizer-coverage-pc-table=1 -S | FileCheck %s
+; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-inline-bool-flag -sanitizer-coverage-pc-table=1 -S | FileCheck %s
 ; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard       -sanitizer-coverage-pc-table=1 -S | FileCheck %s
 ; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-inline-8bit-counters -sanitizer-coverage-pc-table=1 -S | FileCheck %s
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-inline-bool-flag -sanitizer-coverage-pc-table=1 -S | FileCheck %s
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 target triple = "x86_64-unknown-linux-gnu"
Index: llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll
===================================================================
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll
@@ -0,0 +1,13 @@
+; Test -sanitizer-coverage-inline-bool-flag=1
+; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-bool-flag=1  -S | FileCheck %s
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=1 -sanitizer-coverage-inline-bool-flag=1  -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo() {
+entry:
+; CHECK: section "__sancov_bool_flag", comdat($foo), !associated !0
+; CHECK: store i1 true, i1* getelementptr inbounds ([1 x i1], [1 x i1]* @__sancov_gen_, i64 0, i64 0), !nosanitize !1
+  ret void
+}
+; CHECK: call void @__sanitizer_cov_bool_flag_init(i1* bitcast (i1** @__start___sancov_bool_flag to i1*), i1* bitcast (i1** @__stop___sancov_bool_flag to i1*))
Index: llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll
===================================================================
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll
@@ -0,0 +1,13 @@
+; Checks that the PC and 8-bit Counter Arrays are placed in their own sections in COFF binaries.
+; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-bool-flag=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=1 -sanitizer-coverage-inline-bool-flag=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc19.14.26433"
+
+define void @foo() {
+entry:
+  ret void
+}
+
+; CHECK-DAG: section ".SCOV{{\$}}BM",
+; CHECK-DAG: section ".SCOVP{{\$}}M",
Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
===================================================================
--- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -67,6 +67,8 @@
     "sancov.module_ctor_trace_pc_guard";
 static const char *const SanCovModuleCtor8bitCountersName =
     "sancov.module_ctor_8bit_counters";
+static const char *const SanCovModuleCtorBoolFlagName =
+    "sancov.module_ctor_bool_flag";
 static const uint64_t SanCtorAndDtorPriority = 2;
 
 static const char *const SanCovTracePCGuardName =
@@ -75,10 +77,13 @@
     "__sanitizer_cov_trace_pc_guard_init";
 static const char *const SanCov8bitCountersInitName =
     "__sanitizer_cov_8bit_counters_init";
+static const char *const SanCovBoolFlagInitName =
+    "__sanitizer_cov_bool_flag_init";
 static const char *const SanCovPCsInitName = "__sanitizer_cov_pcs_init";
 
 static const char *const SanCovGuardsSectionName = "sancov_guards";
 static const char *const SanCovCountersSectionName = "sancov_cntrs";
+static const char *const SanCovBoolFlagSectionName = "sancov_bool_flag";
 static const char *const SanCovPCsSectionName = "sancov_pcs";
 
 static const char *const SanCovLowestStackName = "__sancov_lowest_stack";
@@ -101,7 +106,8 @@
 // BBs, put this global into a named section, and pass this section's bounds
 // to __sanitizer_cov_pcs_init.
 // This way the coverage instrumentation does not need to acquire the PCs
-// at run-time. Works with trace-pc-guard and inline-8bit-counters.
+// at run-time. Works with trace-pc-guard, inline-8bit-counters, and
+// inline-bool-flag.
 static cl::opt<bool> ClCreatePCTable("sanitizer-coverage-pc-table",
                                      cl::desc("create a static PC table"),
                                      cl::Hidden, cl::init(false));
@@ -111,6 +117,11 @@
                          cl::desc("increments 8-bit counter for every edge"),
                          cl::Hidden, cl::init(false));
 
+static cl::opt<bool>
+    ClInlineBoolFlag("sanitizer-coverage-inline-bool-flag",
+                     cl::desc("sets a boolean flag for every edge"), cl::Hidden,
+                     cl::init(false));
+
 static cl::opt<bool>
     ClCMPTracing("sanitizer-coverage-trace-compares",
                  cl::desc("Tracing of CMP and similar instructions"),
@@ -169,11 +180,13 @@
   Options.TracePC |= ClTracePC;
   Options.TracePCGuard |= ClTracePCGuard;
   Options.Inline8bitCounters |= ClInline8bitCounters;
+  Options.InlineBoolFlag |= ClInlineBoolFlag;
   Options.PCTable |= ClCreatePCTable;
   Options.NoPrune |= !ClPruneBlocks;
   Options.StackDepth |= ClStackDepth;
   if (!Options.TracePCGuard && !Options.TracePC &&
-      !Options.Inline8bitCounters && !Options.StackDepth)
+      !Options.Inline8bitCounters && !Options.StackDepth &&
+      !Options.InlineBoolFlag)
     Options.TracePCGuard = true; // TracePCGuard is default.
   return Options;
 }
@@ -235,7 +248,7 @@
   GlobalVariable *SanCovLowestStack;
   InlineAsm *EmptyAsm;
   Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
-      *Int16Ty, *Int8Ty, *Int8PtrTy;
+      *Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty, *Int1PtrTy;
   Module *CurModule;
   std::string CurModuleUniqueId;
   Triple TargetTriple;
@@ -244,6 +257,7 @@
 
   GlobalVariable *FunctionGuardArray;  // for trace-pc-guard.
   GlobalVariable *Function8bitCounterArray;  // for inline-8bit-counters.
+  GlobalVariable *FunctionBoolArray;         // for inline-bool-flag.
   GlobalVariable *FunctionPCsArray;  // for pc-table.
   SmallVector<GlobalValue *, 20> GlobalsToAppendToUsed;
   SmallVector<GlobalValue *, 20> GlobalsToAppendToCompilerUsed;
@@ -367,6 +381,7 @@
   TargetTriple = Triple(M.getTargetTriple());
   FunctionGuardArray = nullptr;
   Function8bitCounterArray = nullptr;
+  FunctionBoolArray = nullptr;
   FunctionPCsArray = nullptr;
   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
@@ -375,10 +390,12 @@
   Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
   Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
   Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
+  Int1PtrTy = PointerType::getUnqual(IRB.getInt1Ty());
   Int64Ty = IRB.getInt64Ty();
   Int32Ty = IRB.getInt32Ty();
   Int16Ty = IRB.getInt16Ty();
   Int8Ty = IRB.getInt8Ty();
+  Int1Ty = IRB.getInt1Ty();
 
   SanCovTracePCIndir =
       M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy);
@@ -462,6 +479,11 @@
     Ctor = CreateInitCallsForSections(M, SanCovModuleCtor8bitCountersName,
                                       SanCov8bitCountersInitName, Int8PtrTy,
                                       SanCovCountersSectionName);
+  if (FunctionBoolArray) {
+    Ctor = CreateInitCallsForSections(M, SanCovModuleCtorBoolFlagName,
+                                      SanCovBoolFlagInitName, Int1PtrTy,
+                                      SanCovBoolFlagSectionName);
+  }
   if (Ctor && Options.PCTable) {
     auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrPtrTy);
     FunctionCallee InitFunction = declareSanitizerInitFunction(
@@ -701,6 +723,9 @@
   if (Options.Inline8bitCounters)
     Function8bitCounterArray = CreateFunctionLocalArrayInSection(
         AllBlocks.size(), F, Int8Ty, SanCovCountersSectionName);
+  if (Options.InlineBoolFlag)
+    FunctionBoolArray = CreateFunctionLocalArrayInSection(
+        AllBlocks.size(), F, Int1Ty, SanCovBoolFlagSectionName);
 
   if (Options.PCTable)
     FunctionPCsArray = CreatePCArray(F, AllBlocks);
@@ -727,7 +752,8 @@
     Function &F, ArrayRef<Instruction *> IndirCalls) {
   if (IndirCalls.empty())
     return;
-  assert(Options.TracePC || Options.TracePCGuard || Options.Inline8bitCounters);
+  assert(Options.TracePC || Options.TracePCGuard ||
+         Options.Inline8bitCounters || Options.InlineBoolFlag);
   for (auto I : IndirCalls) {
     IRBuilder<> IRB(I);
     CallSite CS(I);
@@ -886,6 +912,15 @@
     SetNoSanitizeMetadata(Load);
     SetNoSanitizeMetadata(Store);
   }
+  if (Options.InlineBoolFlag) {
+    auto FlagPtr = IRB.CreateGEP(
+        FunctionBoolArray->getValueType(), FunctionBoolArray,
+        {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
+    auto Store = IRB.CreateStore(ConstantInt::getTrue(Int1Ty), FlagPtr);
+    Store->setAtomic(AtomicOrdering::NotAtomic);
+    Store->setAlignment(llvm::MaybeAlign(FunctionBoolArray->getAlign()));
+    SetNoSanitizeMetadata(Store);
+  }
   if (Options.StackDepth && IsEntryBB && !IsLeafFunc) {
     // Check stack depth.  If it's the deepest so far, record it.
     Module *M = F.getParent();
@@ -910,6 +945,8 @@
   if (TargetTriple.isOSBinFormatCOFF()) {
     if (Section == SanCovCountersSectionName)
       return ".SCOV$CM";
+    if (Section == SanCovBoolFlagSectionName)
+      return ".SCOV$BM";
     if (Section == SanCovPCsSectionName)
       return ".SCOVP$M";
     return ".SCOV$GM"; // For SanCovGuardsSectionName.
Index: llvm/include/llvm/Transforms/Instrumentation.h
===================================================================
--- llvm/include/llvm/Transforms/Instrumentation.h
+++ llvm/include/llvm/Transforms/Instrumentation.h
@@ -174,6 +174,7 @@
   bool TracePC = false;
   bool TracePCGuard = false;
   bool Inline8bitCounters = false;
+  bool InlineBoolFlag = false;
   bool PCTable = false;
   bool NoPrune = false;
   bool StackDepth = false;
Index: compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp
===================================================================
--- /dev/null
+++ compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp
@@ -0,0 +1,42 @@
+// Tests -fsanitize-coverage=inline-bool-flag,pc-table
+//
+// REQUIRES: has_sancovcc,stable-runtime
+// UNSUPPORTED: i386-darwin
+//
+// RUN: %clangxx -O0 %s -fsanitize-coverage=inline-bool-flag,pc-table -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+// XFAIL: tsan
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+
+const bool *first_flag;
+
+extern "C" void __sanitizer_cov_bool_flag_init(const bool *start,
+                                               const bool *end) {
+  printf("INIT: %p %p\n", start, end);
+  assert(end - start > 1);
+  first_flag = start;
+}
+
+uintptr_t FirstPC;
+uintptr_t FirstPCFlag;
+
+extern "C" void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
+                                         const uintptr_t *pcs_end) {
+  const uintptr_t *B = (const uintptr_t *)pcs_beg;
+  const uintptr_t *E = (const uintptr_t *)pcs_end;
+  assert(B + 1 < E);
+  FirstPC = B[0];
+  FirstPCFlag = B[1];
+}
+
+int main() {
+  assert(first_flag);
+  assert(*first_flag);
+  assert(FirstPC == (uintptr_t)&main);
+  assert(FirstPCFlag == 1);
+  fprintf(stderr, "PASS\n");
+  // CHECK: PASS
+}
Index: clang/test/Driver/fsanitize-coverage.c
===================================================================
--- clang/test/Driver/fsanitize-coverage.c
+++ clang/test/Driver/fsanitize-coverage.c
@@ -105,9 +105,26 @@
 // CHECK_INLINE8BIT-NOT: warning
 // CHECK_INLINE8BIT: -fsanitize-coverage-inline-8bit-counters
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-8bit-counters,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE
-// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE
-// CHECK_PC_TABLE: -fsanitize-coverage-pc-table
+// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-bool-flag %s
+// -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE_BOOL_FLAG RUN: %clang
+// -target x86_64-linux-gnu -fsanitize-coverage=bb,inline-bool-flag %s -### 2>&1
+// | FileCheck %s --check-prefix=CHECK_INLINE_BOOL_FLAG
+// CHECK_INLINE_BOOL_FLAG-NOT: warning
+// CHECK_INLINE_BOOL_FLAG: -fsanitize-coverage-inline-bool-flag
+
+// RUN: %clang -target x86_64-linux-gnu
+// -fsanitize-coverage=inline-8bit-counters,pc-table %s -### 2>&1 | FileCheck %s
+// --check-prefix=CHECK_PC_TABLE_FOR_INLINE8BIT RUN: %clang -target
+// x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard,pc-table %s -### 2>&1 |
+// FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINE8BIT
+// CHECK_PC_TABLE_FOR_INLINE8BIT: -fsanitize-coverage-pc-table
+
+// RUN: %clang -target x86_64-linux-gnu
+// -fsanitize-coverage=inline-bool-flag,pc-table %s -### 2>&1 | FileCheck %s
+// --check-prefix=CHECK_PC_TABLE_FOR_INLINEBOOL RUN: %clang -target
+// x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard,pc-table %s -### 2>&1 |
+// FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINEBOOL
+// CHECK_PC_TABLE_FOR_INLINEBOOL: -fsanitize-coverage-pc-table
 
 // RUN: %clang_cl --target=i386-pc-win32 -fsanitize=address -fsanitize-coverage=func,trace-pc-guard -c -### -- %s 2>&1 | FileCheck %s -check-prefix=CLANG-CL-COVERAGE
 // CLANG-CL-COVERAGE-NOT: error:
Index: clang/test/Driver/autocomplete.c
===================================================================
--- clang/test/Driver/autocomplete.c
+++ clang/test/Driver/autocomplete.c
@@ -45,15 +45,16 @@
 // CLSTDALL-NEXT: CL2.0
 // CLSTDALL-NEXT: clc++
 // CLSTDALL-NEXT: CLC++
-// RUN: %clang --autocomplete=-fno-sanitize-coverage=,f | FileCheck %s -check-prefix=FNOSANICOVER
-// FNOSANICOVER: func
-// RUN: %clang --autocomplete=-fno-sanitize-coverage= | FileCheck %s -check-prefix=FNOSANICOVERALL
-// FNOSANICOVERALL: 8bit-counters
+// RUN: %clang --autocomplete=-fno-sanitize-coverage=,f | FileCheck %s
+// -check-prefix=FNOSANICOVER FNOSANICOVER: func RUN: %clang
+// --autocomplete=-fno-sanitize-coverage= | FileCheck %s
+// -check-prefix=FNOSANICOVERALL FNOSANICOVERALL: 8bit-counters
 // FNOSANICOVERALL-NEXT: bb
 // FNOSANICOVERALL-NEXT: edge
 // FNOSANICOVERALL-NEXT: func
 // FNOSANICOVERALL-NEXT: indirect-calls
 // FNOSANICOVERALL-NEXT: inline-8bit-counters
+// FNOSANICOVERALL-NEXT: inline-bool-flag
 // FNOSANICOVERALL-NEXT: no-prune
 // FNOSANICOVERALL-NEXT: trace-bb
 // FNOSANICOVERALL-NEXT: trace-cmp
@@ -73,21 +74,18 @@
 // FVECLIBALL-NEXT: MASSV
 // FVECLIBALL-NEXT: none
 // FVECLIBALL-NEXT: SVML
-// RUN: %clang --autocomplete=-fshow-overloads= | FileCheck %s -check-prefix=FSOVERALL
-// FSOVERALL: all
-// FSOVERALL-NEXT: best
-// RUN: %clang --autocomplete=-fvisibility= | FileCheck %s -check-prefix=FVISIBILITYALL
+// RUN: %clang --autocomplete=-fshow-overloads= | FileCheck %s
+// -check-prefix=FSOVERALL FSOVERALL: all FSOVERALL-NEXT: best RUN: %clang
+// --autocomplete=-fvisibility= | FileCheck %s -check-prefix=FVISIBILITYALL
 // FVISIBILITYALL: default
 // FVISIBILITYALL-NEXT: hidden
-// RUN: %clang --autocomplete=-mfloat-abi= | FileCheck %s -check-prefix=MFLOATABIALL
-// MFLOATABIALL: hard
-// MFLOATABIALL-NEXT: soft
+// RUN: %clang --autocomplete=-mfloat-abi= | FileCheck %s
+// -check-prefix=MFLOATABIALL MFLOATABIALL: hard MFLOATABIALL-NEXT: soft
 // MFLOATABIALL-NEXT: softfp
-// RUN: %clang --autocomplete=-mthread-model | FileCheck %s -check-prefix=MTHREADMODELALL
-// MTHREADMODELALL: posix
-// MTHREADMODELALL-NEXT: single
-// RUN: %clang --autocomplete=-mrelocation-model | FileCheck %s -check-prefix=MRELOCMODELALL
-// MRELOCMODELALL: dynamic-no-pic
+// RUN: %clang --autocomplete=-mthread-model | FileCheck %s
+// -check-prefix=MTHREADMODELALL MTHREADMODELALL: posix MTHREADMODELALL-NEXT:
+// single RUN: %clang --autocomplete=-mrelocation-model | FileCheck %s
+// -check-prefix=MRELOCMODELALL MRELOCMODELALL: dynamic-no-pic
 // MRELOCMODELALL-NEXT: pic
 // MRELOCMODELALL-NEXT: ropi
 // MRELOCMODELALL-NEXT: ropi-rwpi
@@ -101,25 +99,26 @@
 // WARNING-NEXT: -Wmany-braces-around-scalar-init
 // WARNING-NEXT: -Wmax-tokens
 // WARNING-NEXT: -Wmax-unsigned-zero
-// RUN: %clang --autocomplete=-Wno-invalid-pp- | FileCheck %s -check-prefix=NOWARNING
-// NOWARNING: -Wno-invalid-pp-token
-// RUN: %clang --autocomplete=-analyzer-checker | FileCheck %s -check-prefix=ANALYZER
+// RUN: %clang --autocomplete=-Wno-invalid-pp- | FileCheck %s
+// -check-prefix=NOWARNING NOWARNING: -Wno-invalid-pp-token RUN: %clang
+// --autocomplete=-analyzer-checker | FileCheck %s -check-prefix=ANALYZER
 // ANALYZER: unix.Malloc
 // RUN: %clang --autocomplete=-std= | FileCheck %s -check-prefix=STDVAL
 // STDVAL: c99
 //
 // Clang shouldn't autocomplete CC1 options unless -cc1 or -Xclang were provided
-// RUN: %clang --autocomplete=-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CLANG
-// MRELOCMODEL_CLANG-NOT: -mrelocation-model
-// RUN: %clang --autocomplete=-Xclang,-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CC1
-// RUN: %clang --autocomplete=-cc1,-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CC1
-// MRELOCMODEL_CC1: -mrelocation-model
-// Make sure it ignores passed flags unlesss they are -Xclang or -cc1
-// RUN: %clang --autocomplete=foo,bar,,-fsyn | FileCheck %s -check-prefix=FSYN-CORON
+// RUN: %clang --autocomplete=-mrelocation-mode | FileCheck %s
+// -check-prefix=MRELOCMODEL_CLANG MRELOCMODEL_CLANG-NOT: -mrelocation-model
+// RUN: %clang --autocomplete=-Xclang,-mrelocation-mode | FileCheck %s
+// -check-prefix=MRELOCMODEL_CC1 RUN: %clang
+// --autocomplete=-cc1,-mrelocation-mode | FileCheck %s
+// -check-prefix=MRELOCMODEL_CC1 MRELOCMODEL_CC1: -mrelocation-model Make sure
+// it ignores passed flags unlesss they are -Xclang or -cc1 RUN: %clang
+// --autocomplete=foo,bar,,-fsyn | FileCheck %s -check-prefix=FSYN-CORON
 // FSYN-CORON: -fsyntax-only
 // Check if they can autocomplete values with coron
-// RUN: %clang --autocomplete=foo,bar,,,-fno-sanitize-coverage=,f | FileCheck %s -check-prefix=FNOSANICOVER-CORON
-// FNOSANICOVER-CORON: func
+// RUN: %clang --autocomplete=foo,bar,,,-fno-sanitize-coverage=,f | FileCheck %s
+// -check-prefix=FNOSANICOVER-CORON FNOSANICOVER-CORON: func
 
 // Clang should return empty string when no value completion was found, which will fall back to file autocompletion
 // RUN: %clang --autocomplete=-fmodule-file= | FileCheck %s -check-prefix=MODULE_FILE_EQUAL
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1175,6 +1175,8 @@
   Opts.SanitizeCoverageNoPrune = Args.hasArg(OPT_fsanitize_coverage_no_prune);
   Opts.SanitizeCoverageInline8bitCounters =
       Args.hasArg(OPT_fsanitize_coverage_inline_8bit_counters);
+  Opts.SanitizeCoverageInlineBoolFlag =
+      Args.hasArg(OPT_fsanitize_coverage_inline_bool_flag);
   Opts.SanitizeCoveragePCTable = Args.hasArg(OPT_fsanitize_coverage_pc_table);
   Opts.SanitizeCoverageStackDepth =
       Args.hasArg(OPT_fsanitize_coverage_stack_depth);
Index: clang/lib/Driver/SanitizerArgs.cpp
===================================================================
--- clang/lib/Driver/SanitizerArgs.cpp
+++ clang/lib/Driver/SanitizerArgs.cpp
@@ -77,17 +77,18 @@
   CoverageBB = 1 << 1,
   CoverageEdge = 1 << 2,
   CoverageIndirCall = 1 << 3,
-  CoverageTraceBB = 1 << 4,  // Deprecated.
+  CoverageTraceBB = 1 << 4, // Deprecated.
   CoverageTraceCmp = 1 << 5,
   CoverageTraceDiv = 1 << 6,
   CoverageTraceGep = 1 << 7,
-  Coverage8bitCounters = 1 << 8,  // Deprecated.
+  Coverage8bitCounters = 1 << 8, // Deprecated.
   CoverageTracePC = 1 << 9,
   CoverageTracePCGuard = 1 << 10,
   CoverageNoPrune = 1 << 11,
   CoverageInline8bitCounters = 1 << 12,
   CoveragePCTable = 1 << 13,
   CoverageStackDepth = 1 << 14,
+  CoverageInlineBoolFlag = 1 << 15,
 };
 
 /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
@@ -380,7 +381,8 @@
 
       // Enable coverage if the fuzzing flag is set.
       if (Add & SanitizerKind::FuzzerNoLink) {
-        CoverageFeatures |= CoverageInline8bitCounters | CoverageIndirCall |
+        CoverageFeatures |= CoverageInline8bitCounters |
+                            CoverageInlineBoolFlag | CoverageIndirCall |
                             CoverageTraceCmp | CoveragePCTable;
         // Due to TLS differences, stack depth tracking is only enabled on Linux
         if (TC.getTriple().isOSLinux())
@@ -723,8 +725,9 @@
         << "-fsanitize-coverage=trace-pc-guard";
 
   int InsertionPointTypes = CoverageFunc | CoverageBB | CoverageEdge;
-  int InstrumentationTypes =
-      CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters;
+  int InstrumentationTypes = CoverageTracePC | CoverageTracePCGuard |
+                             CoverageInline8bitCounters |
+                             CoverageInlineBoolFlag;
   if ((CoverageFeatures & InsertionPointTypes) &&
       !(CoverageFeatures & InstrumentationTypes)) {
     D.Diag(clang::diag::warn_drv_deprecated_arg)
@@ -735,7 +738,8 @@
   // trace-pc w/o func/bb/edge implies edge.
   if (!(CoverageFeatures & InsertionPointTypes)) {
     if (CoverageFeatures &
-        (CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters))
+        (CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters |
+         CoverageInlineBoolFlag))
       CoverageFeatures |= CoverageEdge;
 
     if (CoverageFeatures & CoverageStackDepth)
@@ -907,21 +911,25 @@
   // Do it even if Sanitizers.empty() since some forms of coverage don't require
   // sanitizers.
   std::pair<int, const char *> CoverageFlags[] = {
-    std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
-    std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
-    std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
-    std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
-    std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
-    std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
-    std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"),
-    std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
-    std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
-    std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
-    std::make_pair(CoverageTracePCGuard, "-fsanitize-coverage-trace-pc-guard"),
-    std::make_pair(CoverageInline8bitCounters, "-fsanitize-coverage-inline-8bit-counters"),
-    std::make_pair(CoveragePCTable, "-fsanitize-coverage-pc-table"),
-    std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune"),
-    std::make_pair(CoverageStackDepth, "-fsanitize-coverage-stack-depth")};
+      std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
+      std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
+      std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
+      std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
+      std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
+      std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
+      std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"),
+      std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
+      std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
+      std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
+      std::make_pair(CoverageTracePCGuard,
+                     "-fsanitize-coverage-trace-pc-guard"),
+      std::make_pair(CoverageInline8bitCounters,
+                     "-fsanitize-coverage-inline-8bit-counters"),
+      std::make_pair(CoverageInlineBoolFlag,
+                     "-fsanitize-coverage-inline-bool-flag"),
+      std::make_pair(CoveragePCTable, "-fsanitize-coverage-pc-table"),
+      std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune"),
+      std::make_pair(CoverageStackDepth, "-fsanitize-coverage-stack-depth")};
   for (auto F : CoverageFlags) {
     if (CoverageFeatures & F.first)
       CmdArgs.push_back(F.second);
@@ -1105,22 +1113,23 @@
   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
     const char *Value = A->getValue(i);
     int F = llvm::StringSwitch<int>(Value)
-        .Case("func", CoverageFunc)
-        .Case("bb", CoverageBB)
-        .Case("edge", CoverageEdge)
-        .Case("indirect-calls", CoverageIndirCall)
-        .Case("trace-bb", CoverageTraceBB)
-        .Case("trace-cmp", CoverageTraceCmp)
-        .Case("trace-div", CoverageTraceDiv)
-        .Case("trace-gep", CoverageTraceGep)
-        .Case("8bit-counters", Coverage8bitCounters)
-        .Case("trace-pc", CoverageTracePC)
-        .Case("trace-pc-guard", CoverageTracePCGuard)
-        .Case("no-prune", CoverageNoPrune)
-        .Case("inline-8bit-counters", CoverageInline8bitCounters)
-        .Case("pc-table", CoveragePCTable)
-        .Case("stack-depth", CoverageStackDepth)
-        .Default(0);
+                .Case("func", CoverageFunc)
+                .Case("bb", CoverageBB)
+                .Case("edge", CoverageEdge)
+                .Case("indirect-calls", CoverageIndirCall)
+                .Case("trace-bb", CoverageTraceBB)
+                .Case("trace-cmp", CoverageTraceCmp)
+                .Case("trace-div", CoverageTraceDiv)
+                .Case("trace-gep", CoverageTraceGep)
+                .Case("8bit-counters", Coverage8bitCounters)
+                .Case("trace-pc", CoverageTracePC)
+                .Case("trace-pc-guard", CoverageTracePCGuard)
+                .Case("no-prune", CoverageNoPrune)
+                .Case("inline-8bit-counters", CoverageInline8bitCounters)
+                .Case("inline-bool-flag", CoverageInlineBoolFlag)
+                .Case("pc-table", CoveragePCTable)
+                .Case("stack-depth", CoverageStackDepth)
+                .Default(0);
     if (F == 0)
       D.Diag(clang::diag::err_drv_unsupported_option_argument)
           << A->getOption().getName() << Value;
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -222,6 +222,7 @@
   Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;
   Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;
   Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;
+  Opts.InlineBoolFlag = CGOpts.SanitizeCoverageInlineBoolFlag;
   Opts.PCTable = CGOpts.SanitizeCoveragePCTable;
   Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;
   return Opts;
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -901,7 +901,7 @@
 def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<f_Group>,
     HelpText<"Print option name with mappable diagnostics">;
 def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">,
-    Group<f_Group>,  Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">;
+    Group<f_Group>, Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">;
 def fdiagnostics_format_EQ : Joined<["-"], "fdiagnostics-format=">, Group<f_clang_Group>;
 def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category=">, Group<f_clang_Group>;
 def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tree">,
@@ -1019,7 +1019,7 @@
     : CommaJoined<["-"], "fno-sanitize-coverage=">,
       Group<f_clang_Group>, Flags<[CoreOption, DriverOption]>,
       HelpText<"Disable specified features of coverage instrumentation for "
-               "Sanitizers">, Values<"func,bb,edge,indirect-calls,trace-bb,trace-cmp,trace-div,trace-gep,8bit-counters,trace-pc,trace-pc-guard,no-prune,inline-8bit-counters">;
+               "Sanitizers">, Values<"func,bb,edge,indirect-calls,trace-bb,trace-cmp,trace-div,trace-gep,8bit-counters,trace-pc,trace-pc-guard,no-prune,inline-8bit-counters,inline-bool-flag">;
 def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
                                         Group<f_clang_Group>,
                                         HelpText<"Enable origins tracking in MemorySanitizer">;
Index: clang/include/clang/Driver/CC1Options.td
===================================================================
--- clang/include/clang/Driver/CC1Options.td
+++ clang/include/clang/Driver/CC1Options.td
@@ -355,6 +355,9 @@
 def fsanitize_coverage_inline_8bit_counters
     : Flag<["-"], "fsanitize-coverage-inline-8bit-counters">,
       HelpText<"Enable inline 8-bit counters in sanitizer coverage">;
+def fsanitize_coverage_inline_bool_flag
+    : Flag<["-"], "fsanitize-coverage-inline-bool-flag">,
+      HelpText<"Enable inline bool flag in sanitizer coverage">;
 def fsanitize_coverage_pc_table
     : Flag<["-"], "fsanitize-coverage-pc-table">,
       HelpText<"Create a table of coverage-instrumented PCs">;
Index: clang/include/clang/Basic/CodeGenOptions.def
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -232,6 +232,7 @@
 CODEGENOPT(SanitizeCoverageTracePCGuard, 1, 0) ///< Enable PC tracing with guard
                                                ///< in sanitizer coverage.
 CODEGENOPT(SanitizeCoverageInline8bitCounters, 1, 0) ///< Use inline 8bit counters.
+CODEGENOPT(SanitizeCoverageInlineBoolFlag, 1, 0) ///< Use inline bool flag.
 CODEGENOPT(SanitizeCoveragePCTable, 1, 0) ///< Create a PC Table.
 CODEGENOPT(SanitizeCoverageNoPrune, 1, 0) ///< Disable coverage pruning.
 CODEGENOPT(SanitizeCoverageStackDepth, 1, 0) ///< Enable max stack depth tracing
Index: clang/docs/SanitizerCoverage.rst
===================================================================
--- clang/docs/SanitizerCoverage.rst
+++ clang/docs/SanitizerCoverage.rst
@@ -139,6 +139,28 @@
     // Capture this array in order to read/modify the counters.
   }
 
+
+Inline bool-flag
+================
+
+**Experimental, may change or disappear in future**
+
+With ``-fsanitize-coverage=inline-bool-flag`` the compiler will insert
+setting an inline boolean to true on every edge.
+This is similar to ``-fsanitize-coverage=inline-8bit-counter`` but instead of
+an increment of a counter, it just sets a boolean to true.
+
+Users need to implement a single function to capture the counters at startup.
+
+.. code-block:: c++
+
+  extern "C"
+  void __sanitizer_cov_bool_flag_init(bool *start, bool *end) {
+    // [start,end) is the array of boolean flags created for the current DSO.
+    // Capture this array in order to read/modify the flags.
+  }
+
+
 PC-Table
 ========
 
@@ -150,8 +172,8 @@
 `Bug 34636 <https://bugs.llvm.org/show_bug.cgi?id=34636>`_.
 
 With ``-fsanitize-coverage=pc-table`` the compiler will create a table of
-instrumented PCs. Requires either ``-fsanitize-coverage=inline-8bit-counters`` or
-``-fsanitize-coverage=trace-pc-guard``.
+instrumented PCs. Requires either ``-fsanitize-coverage=inline-8bit-counters``,
+or ``-fsanitize-coverage=inline-bool-flag``, or ``-fsanitize-coverage=trace-pc-guard``.
 
 Users need to implement a single function to capture the PC table at startup:
 
@@ -164,8 +186,9 @@
     // pairs [PC,PCFlags] for every instrumented block in the current DSO.
     // Capture this array in order to read the PCs and their Flags.
     // The number of PCs and PCFlags for a given DSO is the same as the number
-    // of 8-bit counters (-fsanitize-coverage=inline-8bit-counters) or
-    // trace_pc_guard callbacks (-fsanitize-coverage=trace-pc-guard)
+    // of 8-bit counters (-fsanitize-coverage=inline-8bit-counters), or
+    // boolean flags (-fsanitize-coverage=inline=bool-flags), or trace_pc_guard
+    // callbacks (-fsanitize-coverage=trace-pc-guard).
     // A PCFlags describes the basic block:
     //  * bit0: 1 if the block is the function entry block, 0 otherwise.
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to