Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -851,20 +851,23 @@ bool CollisionDetected = false; bool FindCollision(const std::pair &BlockState) { - auto Ins = InboundState.insert(BlockState); - if (!Ins.second) { - // Already there. Return collision if they are different. - return BlockState.second != Ins.first->second; - } - - // Use marker for successors if block contains any. - auto M = Markers.find(BlockState.first); - bool NewState = (M != Markers.end() ? M->second : BlockState.second); - for (const BasicBlock *SB : successors(BlockState.first)) + for (const BasicBlock *SB : successors(BlockState.first)) { // We may get into EHPad with any lifetime state, so ignore them. - if (!SB->isEHPad() && FindCollision({SB, NewState})) - return true; + if (SB->isEHPad()) + continue; + std::pair NewState = {SB, BlockState.second}; + auto Ins = InboundState.insert(NewState); + if (!Ins.second) { + // Already there. Return collision if they are different. + if (NewState.second != Ins.first->second) + return true; + } else { + // Don't recurse into markers, we will start search from each of them. + if (Markers.find(SB) == Markers.end() && FindCollision(NewState)) + return true; + } + } return false; } @@ -880,8 +883,11 @@ bool HasAmbiguousLifetime() { if (!Processed) { Processed = true; - const Function *F = Markers.begin()->first->getParent(); - CollisionDetected = FindCollision({&F->getEntryBlock(), false}); + for (const auto& M : Markers) { + CollisionDetected = FindCollision(M); + if (CollisionDetected) + break; + } } return CollisionDetected; } @@ -2373,12 +2379,18 @@ IRB.CreateStore(IRB.CreatePointerCast(&F, IntptrTy), BasePlus2); const auto &ShadowAfterScope = GetShadowBytesAfterScope(SVD, L); + const auto &ShadowInScope = GetShadowBytes(SVD, L); // Poison the stack red zones at the entry. Value *ShadowBase = ASan.memToShadow(LocalStackBase, IRB); // As mask we must use most poisoned case: red zones and after scope. - // As bytes we can use either the same or just red zones only. - copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase); + // In most cases as bytes we can use either the same or just red zones only. + // However PR28267 allows functions with several branches, when some + // branches have proper sets of lifetime.start/lifetime.end, and some have + // none at all. To avoid reports in such cases we assume that on entry + // variable is alive, and it will be poisoned only by lifetime.end. + // So we poison frame with red zones only, like var inside of the scope. + copyToShadow(ShadowAfterScope, ShadowInScope, IRB, ShadowBase); if (ClExperimentalPoisoning && !StaticAllocaPoisonCallVec.empty()) { // Complete AllocaToSVDMap @@ -2389,8 +2401,6 @@ } } - const auto &ShadowInScope = GetShadowBytes(SVD, L); - // Poison static allocas near lifetime intrinsics. for (const auto &APC : StaticAllocaPoisonCallVec) { // Must be already set. Index: test/Instrumentation/AddressSanitizer/lifetime-throw.ll =================================================================== --- test/Instrumentation/AddressSanitizer/lifetime-throw.ll +++ test/Instrumentation/AddressSanitizer/lifetime-throw.ll @@ -20,8 +20,8 @@ %x = alloca %struct.ABC, align 4 %0 = bitcast %struct.ABC* %x to i8* - ; Poison memory in prologue: F1F1F1F1F8F3F3F3 - ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}} + ; Poison memory in prologue: F1F1F1F104F3F3F3 + ; CHECK: store i64 -868083100587789839, i64* %{{[0-9]+}} call void @llvm.lifetime.start(i64 4, i8* %0) ; CHECK: store i8 4, i8* %{{[0-9]+}} @@ -74,8 +74,8 @@ %tmp = alloca %struct.ABC, align 4 %0 = bitcast %struct.ABC* %x to i8* - ; Poison memory in prologue: F1F1F1F1F8F304F2 - ; CHECK: store i64 -935355671561244175, i64* %{{[0-9]+}} + ; Poison memory in prologue: F1F1F1F104F204F3 + ; CHECK: store i64 -935356719533264399, i64* %{{[0-9]+}} call void @llvm.lifetime.start(i64 4, i8* %0) ; CHECK: store i8 4, i8* %{{[0-9]+}} Index: test/Instrumentation/AddressSanitizer/lifetime-uar-uas.ll =================================================================== --- test/Instrumentation/AddressSanitizer/lifetime-uar-uas.ll +++ test/Instrumentation/AddressSanitizer/lifetime-uar-uas.ll @@ -16,8 +16,8 @@ %retval = alloca i32, align 4 %c = alloca i8, align 1 - ; Memory is poisoned in prologue: F1F1F1F104F3F8F2 - ; CHECK-UAS: store i64 -866676825215864335, i64* %{{[0-9]+}} + ; Memory is poisoned in prologue: F1F1F1F104F201F3 + ; CHECK-UAS: store i64 -936201144463396367, i64* %{{[0-9]+}} call void @llvm.lifetime.start(i64 1, i8* %c) ; Memory is unpoisoned at llvm.lifetime.start: 01 Index: test/Instrumentation/AddressSanitizer/lifetime.ll =================================================================== --- test/Instrumentation/AddressSanitizer/lifetime.ll +++ test/Instrumentation/AddressSanitizer/lifetime.ll @@ -45,8 +45,8 @@ %i = alloca i32, align 4 %i.ptr = bitcast i32* %i to i8* - ; Poison memory in prologue: F1F1F1F1F8F3F3F3 - ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}} + ; Poison memory in prologue: F1F1F1F104F3F3F3 + ; CHECK: store i64 -868083100587789839, i64* %{{[0-9]+}} ; Memory is unpoisoned at llvm.lifetime.start call void @llvm.lifetime.start(i64 3, i8* %i.ptr) @@ -111,6 +111,11 @@ ; CHECK: store i8 1, i8* %{{[0-9]+}} ; CHECK-NEXT: call void @llvm.lifetime.start + call void @llvm.lifetime.end(i64 1, i8* %j) + ; CHECK-DEFAULT-NOT: store i8 -8, i8* %{{[0-9]+}} + ; CHECK-AMBIGUOUS: store i8 -8, i8* %{{[0-9]+}} + ; CHECK-NEXT: call void @llvm.lifetime.end + br i1 %x, label %bb0, label %bb1 bb0: @@ -149,8 +154,8 @@ %i = alloca i64, align 4 %i.ptr = bitcast i64* %i to i8* - ; Poison memory in prologue: F1F1F1F1F8F3F3F3 - ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}} + ; Poison memory in prologue: F1F1F1F100F3F3F3 + ; CHECK: store i64 -868083117767659023, i64* %{{[0-9]+}} call void @llvm.lifetime.start(i64 8, i8* %i.ptr) ; CHECK: store i8 0, i8* %{{[0-9]+}} Index: test/Instrumentation/AddressSanitizer/stack-poisoning-experimental-be.ll =================================================================== --- test/Instrumentation/AddressSanitizer/stack-poisoning-experimental-be.ll +++ test/Instrumentation/AddressSanitizer/stack-poisoning-experimental-be.ll @@ -66,32 +66,32 @@ ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i32]]* ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -235802127, [[TYPE]]* [[PTR]], align 1 - ; F8F8F8... + ; 000000... ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 4 - ; ENTRY-UAS-EXP-NEXT: call void @__asan_set_shadow_f8(i64 [[OFFSET]], i64 82) + ; ENTRY-UAS-EXP-NEXT: call void @__asan_set_shadow_00(i64 [[OFFSET]], i64 81) - ; F2F2F2F2F2F2F2F2 - ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 86 + ; F2F2F2F2F2F2F202 + ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 85 ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i64]]* - ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -940422246894996750, [[TYPE]]* [[PTR]], align 1 + ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] 212499257711850226, [[TYPE]]* [[PTR]], align 1 ; F2F2F2F2F2F2F2F2 - ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 94 + ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 93 ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i64]]* ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -940422246894996750, [[TYPE]]* [[PTR]], align 1 - ; F8F8F2F2F8F8F8F8 - ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 102 + ; 000000F2F20500F2 + ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 101 ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i64]]* - ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -506387832706107144, [[TYPE]]* [[PTR]], align 1 + ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -1008799775530680320, [[TYPE]]* [[PTR]], align 1 - ; F8F3F3F3 - ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 110 + ; F3F30000 + ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 109 ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i32]]* - ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -118230029, [[TYPE]]* [[PTR]], align 1 + ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] 62451, [[TYPE]]* [[PTR]], align 1 ; F3F3 - ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 114 + ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 113 ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i16]]* ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -3085, [[TYPE]]* [[PTR]], align 1 Index: test/Instrumentation/AddressSanitizer/stack-poisoning-experimental.ll =================================================================== --- test/Instrumentation/AddressSanitizer/stack-poisoning-experimental.ll +++ test/Instrumentation/AddressSanitizer/stack-poisoning-experimental.ll @@ -66,32 +66,32 @@ ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i32]]* ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -235802127, [[TYPE]]* [[PTR]], align 1 - ; F8F8F8... + ; 000000... ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 4 - ; ENTRY-UAS-EXP-NEXT: call void @__asan_set_shadow_f8(i64 [[OFFSET]], i64 82) + ; ENTRY-UAS-EXP-NEXT: call void @__asan_set_shadow_00(i64 [[OFFSET]], i64 81) - ; F2F2F2F2F2F2F2F2 - ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 86 + ; 02F2F2F2F2F2F2F2 + ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 85 ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i64]]* - ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -940422246894996750, [[TYPE]]* [[PTR]], align 1 + ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -940422246894996990, [[TYPE]]* [[PTR]], align 1 ; F2F2F2F2F2F2F2F2 - ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 94 + ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 93 ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i64]]* ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -940422246894996750, [[TYPE]]* [[PTR]], align 1 - ; F8F8F2F2F8F8F8F8 - ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 102 + ; F20005F2F2000000 + ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 101 ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i64]]* - ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -506381209967593224, [[TYPE]]* [[PTR]], align 1 + ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] 1043442499826, [[TYPE]]* [[PTR]], align 1 - ; F8F3F3F3 - ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 110 + ; 0000F3F3 + ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 109 ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i32]]* - ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -202116104, [[TYPE]]* [[PTR]], align 1 + ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -202178560, [[TYPE]]* [[PTR]], align 1 ; F3F3 - ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 114 + ; ENTRY-UAS-EXP-NEXT: [[OFFSET:%[0-9]+]] = add i64 [[SHADOW_BASE]], 113 ; ENTRY-UAS-EXP-NEXT: [[PTR:%[0-9]+]] = inttoptr i64 [[OFFSET]] to [[TYPE:i16]]* ; ENTRY-UAS-EXP-NEXT: store [[TYPE]] -3085, [[TYPE]]* [[PTR]], align 1