Skip to content

Commit 2bcca88

Browse files
committed
[Sanitizer] Make sanitizer passes idempotent.
1 parent 1399637 commit 2bcca88

File tree

12 files changed

+208
-2
lines changed

12 files changed

+208
-2
lines changed

clang/test/CodeGenObjC/no-sanitize.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
@interface I0 @end
44
@implementation I0
5-
// CHECK-NOT: sanitize_address
5+
// CHECK-NOT: Function Attrs: sanitize_address
66
- (void) im0: (int) a0 __attribute__((no_sanitize("address"))) {
77
int (^blockName)(void) = ^int(void) { return 0; };
88
}

llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,12 @@ AddressSanitizerPass::AddressSanitizerPass(
12511251

12521252
PreservedAnalyses AddressSanitizerPass::run(Module &M,
12531253
ModuleAnalysisManager &MAM) {
1254+
// Return early if nosanitize_address module flag is present for the module.
1255+
// This implies that asan pass has already run before.
1256+
if (M.getModuleFlag("nosanitize_address"))
1257+
return PreservedAnalyses::all();
1258+
M.addModuleFlag(Module::ModFlagBehavior::Override, "nosanitize_address", 1);
1259+
12541260
ModuleAddressSanitizer ModuleSanitizer(
12551261
M, Options.InsertVersionCheck, Options.CompileKernel, Options.Recover,
12561262
UseGlobalGC, UseOdrIndicator, DestructorKind, ConstructorKind);

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3473,6 +3473,10 @@ void DFSanVisitor::visitPHINode(PHINode &PN) {
34733473

34743474
PreservedAnalyses DataFlowSanitizerPass::run(Module &M,
34753475
ModuleAnalysisManager &AM) {
3476+
// Return early if nosanitize_dataflow module flag is present for the module.
3477+
if (M.getModuleFlag("nosanitize_dataflow"))
3478+
return PreservedAnalyses::all();
3479+
M.addModuleFlag(Module::ModFlagBehavior::Override, "nosanitize_dataflow", 1);
34763480
auto GetTLI = [&](Function &F) -> TargetLibraryInfo & {
34773481
auto &FAM =
34783482
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,10 @@ class HWAddressSanitizer {
455455

456456
PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
457457
ModuleAnalysisManager &MAM) {
458+
// Return early if nosanitize_hwaddress module flag is present for the module.
459+
if (M.getModuleFlag("nosanitize_hwaddress"))
460+
return PreservedAnalyses::all();
461+
M.addModuleFlag(Module::ModFlagBehavior::Override, "nosanitize_hwaddress", 1);
458462
const StackSafetyGlobalInfo *SSI = nullptr;
459463
auto TargetTriple = llvm::Triple(M.getTargetTriple());
460464
if (shouldUseStackSafetyAnalysis(TargetTriple, Options.DisableOptimization))

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,10 @@ MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K,
706706

707707
PreservedAnalyses MemorySanitizerPass::run(Module &M,
708708
ModuleAnalysisManager &AM) {
709+
// Return early if nosanitize_memory module flag is present for the module.
710+
if (M.getModuleFlag("nosanitize_memory"))
711+
return PreservedAnalyses::all();
712+
M.addModuleFlag(Module::ModFlagBehavior::Override, "nosanitize_memory", 1);
709713
bool Modified = false;
710714
if (!Options.Kernel) {
711715
insertModuleCtor(M);

llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ PreservedAnalyses ThreadSanitizerPass::run(Function &F,
191191

192192
PreservedAnalyses ModuleThreadSanitizerPass::run(Module &M,
193193
ModuleAnalysisManager &MAM) {
194+
// Return early if nosanitize_thread module flag is present for the module.
195+
if (M.getModuleFlag("nosanitize_thread"))
196+
return PreservedAnalyses::all();
197+
M.addModuleFlag(Module::ModFlagBehavior::Override, "nosanitize_thread", 1);
194198
insertModuleCtor(M);
195199
return PreservedAnalyses::none();
196200
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5
2+
; This test checks in the second run, function is not instrumented again.
3+
; RUN: opt < %s -passes=asan,asan -S | FileCheck %s
4+
5+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6+
target triple = "x86_64-unknown-linux-gnu"
7+
8+
; Function with sanitize_address is instrumented.
9+
; Function Attrs: nounwind uwtable
10+
;.
11+
; CHECK: @___asan_globals_registered = common hidden global i64 0
12+
; CHECK: @__start_asan_globals = extern_weak hidden global i64
13+
; CHECK: @__stop_asan_globals = extern_weak hidden global i64
14+
;.
15+
define void @instr_sa(ptr %a) sanitize_address {
16+
; CHECK: Function Attrs: sanitize_address
17+
; CHECK-LABEL: define void @instr_sa(
18+
; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
19+
; CHECK-NEXT: [[ENTRY:.*:]]
20+
; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
21+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[TMP0]], 3
22+
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 2147450880
23+
; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr
24+
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
25+
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i8 [[TMP4]], 0
26+
; CHECK-NEXT: br i1 [[TMP5]], label %[[BB6:.*]], label %[[BB12:.*]], !prof [[PROF1:![0-9]+]]
27+
; CHECK: [[BB6]]:
28+
; CHECK-NEXT: [[TMP7:%.*]] = and i64 [[TMP0]], 7
29+
; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[TMP7]], 3
30+
; CHECK-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i8
31+
; CHECK-NEXT: [[TMP10:%.*]] = icmp sge i8 [[TMP9]], [[TMP4]]
32+
; CHECK-NEXT: br i1 [[TMP10]], label %[[BB11:.*]], label %[[BB12]]
33+
; CHECK: [[BB11]]:
34+
; CHECK-NEXT: call void @__asan_report_load4(i64 [[TMP0]]) #[[ATTR2:[0-9]+]]
35+
; CHECK-NEXT: unreachable
36+
; CHECK: [[BB12]]:
37+
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4
38+
; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
39+
; CHECK-NEXT: store i32 [[TMP2]], ptr [[A]], align 4
40+
; CHECK-NEXT: ret void
41+
;
42+
entry:
43+
%tmp1 = load i32, ptr %a, align 4
44+
%tmp2 = add i32 %tmp1, 1
45+
store i32 %tmp2, ptr %a, align 4
46+
ret void
47+
}
48+
;.
49+
; CHECK: attributes #[[ATTR0]] = { sanitize_address }
50+
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
51+
; CHECK: attributes #[[ATTR2]] = { nomerge }
52+
;.
53+
; CHECK: [[META0:![0-9]+]] = !{i32 4, !"nosanitize_address", i32 1}
54+
; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 1048575}
55+
;.

llvm/test/Instrumentation/AddressSanitizer/missing_dbg.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ entry:
3434
!4 = !DISubroutineType(types: !5)
3535
!5 = !{}
3636

37-
; CHECK: [[DBG]] = !DILocation(line: 0, scope: !3)
37+
; CHECK: [[DBG]] = !DILocation(line: 0, scope: !4)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
; RUN: opt < %s -passes=dfsan,dfsan -S | FileCheck %s
2+
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-S128"
3+
target triple = "x86_64-unknown-linux-gnu"
4+
5+
define i8 @add(i8 %a, i8 %b) {
6+
; CHECK: @add.dfsan
7+
; CHECK-DAG: %[[#ALABEL:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
8+
; CHECK-DAG: %[[#BLABEL:]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN]]
9+
; CHECK: %[[#UNION:]] = or i8 %[[#ALABEL]], %[[#BLABEL]]
10+
; CHECK: %c = add i8 %a, %b
11+
; CHECK: store i8 %[[#UNION]], ptr @__dfsan_retval_tls, align [[ALIGN]]
12+
; CHECK: ret i8 %c
13+
%c = add i8 %a, %b
14+
ret i8 %c
15+
}
16+
17+
; CHECK: [[META0:![0-9]+]] = !{i32 4, !"nosanitize_dataflow", i32 1}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals --version 2
2+
; Test basic address sanitizer instrumentation.
3+
;
4+
; RUN: opt < %s -passes=hwasan,hwasan -S | FileCheck %s
5+
6+
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-S128"
7+
target triple = "x86_64-unknown-linux-gnu"
8+
9+
;.
10+
; CHECK: @llvm.used = appending global [1 x ptr] [ptr @hwasan.module_ctor], section "llvm.metadata"
11+
; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @hwasan.module_ctor, ptr @hwasan.module_ctor }]
12+
; CHECK: @__start_hwasan_globals = external hidden constant [0 x i8]
13+
; CHECK: @__stop_hwasan_globals = external hidden constant [0 x i8]
14+
; CHECK: @hwasan.note = private constant { i32, i32, i32, [8 x i8], i32, i32 } { i32 8, i32 8, i32 3, [8 x i8] c"LLVM\00\00\00\00", i32 trunc (i64 sub (i64 ptrtoint (ptr @__start_hwasan_globals to i64), i64 ptrtoint (ptr @hwasan.note to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @__stop_hwasan_globals to i64), i64 ptrtoint (ptr @hwasan.note to i64)) to i32) }, section ".note.hwasan.globals", comdat($hwasan.module_ctor), align 4
15+
; CHECK: @hwasan.dummy.global = private constant [0 x i8] zeroinitializer, section "hwasan_globals", comdat($hwasan.module_ctor), !associated [[META0:![0-9]+]]
16+
; CHECK: @__hwasan_tls = external thread_local(initialexec) global i64
17+
; CHECK: @llvm.compiler.used = appending global [3 x ptr] [ptr @hwasan.note, ptr @hwasan.dummy.global, ptr @__hwasan_tls], section "llvm.metadata"
18+
; CHECK: @__hwasan_shadow = external global [0 x i8]
19+
;.
20+
define i8 @test_load8(ptr %a) sanitize_hwaddress {
21+
; CHECK: Function Attrs: sanitize_hwaddress
22+
; CHECK-LABEL: define i8 @test_load8
23+
; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
24+
; CHECK-NEXT: entry:
25+
; CHECK-NEXT: [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
26+
; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
27+
; CHECK-NEXT: call void @__hwasan_load1(i64 [[TMP0]])
28+
; CHECK-NEXT: [[B:%.*]] = load i8, ptr [[A]], align 4
29+
; CHECK-NEXT: ret i8 [[B]]
30+
;
31+
entry:
32+
%b = load i8, ptr %a, align 4
33+
ret i8 %b
34+
}
35+
;.
36+
; CHECK: attributes #[[ATTR0]] = { sanitize_hwaddress }
37+
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind }
38+
;.
39+
; CHECK: [[META0]] = !{ptr @hwasan.note}
40+
; CHECK: [[META1:![0-9]+]] = !{i32 4, !"nosanitize_hwaddress", i32 1}
41+
;.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5
2+
; This test checks in the second run, function is not instrumented again.
3+
; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan,msan | FileCheck %s
4+
5+
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-S128"
6+
target triple = "x86_64-unknown-linux-gnu"
7+
8+
;.
9+
; CHECK: @llvm.used = appending global [1 x ptr] [ptr @msan.module_ctor], section "llvm.metadata"
10+
; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @msan.module_ctor, ptr null }]
11+
; CHECK: @__msan_retval_tls = external thread_local(initialexec) global [100 x i64]
12+
; CHECK: @__msan_retval_origin_tls = external thread_local(initialexec) global i32
13+
; CHECK: @__msan_param_tls = external thread_local(initialexec) global [100 x i64]
14+
; CHECK: @__msan_param_origin_tls = external thread_local(initialexec) global [200 x i32]
15+
; CHECK: @__msan_va_arg_tls = external thread_local(initialexec) global [100 x i64]
16+
; CHECK: @__msan_va_arg_origin_tls = external thread_local(initialexec) global [200 x i32]
17+
; CHECK: @__msan_va_arg_overflow_size_tls = external thread_local(initialexec) global i64
18+
;.
19+
define void @array() sanitize_memory {
20+
; CHECK: Function Attrs: sanitize_memory
21+
; CHECK-LABEL: define void @array(
22+
; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
23+
; CHECK-NEXT: [[ENTRY:.*:]]
24+
; CHECK-NEXT: call void @llvm.donothing()
25+
; CHECK-NEXT: [[X:%.*]] = alloca i32, i64 5, align 4
26+
; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[X]] to i64
27+
; CHECK-NEXT: [[TMP1:%.*]] = xor i64 [[TMP0]], 87960930222080
28+
; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to ptr
29+
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP2]], i8 -1, i64 20, i1 false)
30+
; CHECK-NEXT: ret void
31+
;
32+
entry:
33+
%x = alloca i32, i64 5, align 4
34+
ret void
35+
}
36+
;.
37+
; CHECK: attributes #[[ATTR0]] = { sanitize_memory }
38+
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind }
39+
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(none) }
40+
; CHECK: attributes #[[ATTR3:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
41+
;.
42+
; CHECK: [[META0:![0-9]+]] = !{i32 4, !"nosanitize_memory", i32 1}
43+
;.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals --version 2
2+
; RUN: opt < %s -passes=tsan-module,tsan-module -S | FileCheck %s
3+
4+
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-S128"
5+
6+
declare void @can_throw()
7+
declare void @cannot_throw() nounwind
8+
9+
;.
10+
; CHECK: @llvm.used = appending global [1 x ptr] [ptr @tsan.module_ctor], section "llvm.metadata"
11+
; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tsan.module_ctor, ptr null }]
12+
;.
13+
define i32 @func1() sanitize_thread {
14+
; CHECK: Function Attrs: sanitize_thread
15+
; CHECK-LABEL: define i32 @func1
16+
; CHECK-SAME: () #[[ATTR1:[0-9]+]] {
17+
; CHECK-NEXT: call void @can_throw()
18+
; CHECK-NEXT: ret i32 0
19+
;
20+
call void @can_throw()
21+
ret i32 0
22+
}
23+
;.
24+
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind }
25+
; CHECK: attributes #[[ATTR1]] = { sanitize_thread }
26+
;.
27+
; CHECK: [[META0:![0-9]+]] = !{i32 4, !"nosanitize_thread", i32 1}
28+
;.

0 commit comments

Comments
 (0)