msan, codegen, instcombine: Keep more lifetime markers used for msan

Reviewers: eugenis

Subscribers: hiraditya, cfe-commits, #sanitizers, llvm-commits

Tags: #clang, #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D66695

llvm-svn: 369979
This commit is contained in:
Vitaly Buka 2019-08-26 22:15:50 +00:00
parent 173a3a54bb
commit aeca56964f
7 changed files with 46 additions and 11 deletions

View File

@ -516,13 +516,12 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
// Avoid creating a conditional cleanup just to hold an llvm.lifetime.end
// marker. Instead, start the lifetime of a conditional temporary earlier
// so that it's unconditional. Don't do this in ASan's use-after-scope
// mode so that it gets the more precise lifetime marks. If the type has
// a non-trivial destructor, we'll have a cleanup block for it anyway,
// so this typically doesn't help; skip it in that case.
// so that it's unconditional. Don't do this with sanitizers which need
// more precise lifetime marks.
ConditionalEvaluation *OldConditional = nullptr;
CGBuilderTy::InsertPoint OldIP;
if (isInConditionalBranch() && !E->getType().isDestructedType() &&
!SanOpts.has(SanitizerKind::Memory) &&
!CGM.getCodeGenOpts().SanitizeAddressUseAfterScope) {
OldConditional = OutermostConditional;
OutermostConditional = nullptr;

View File

@ -47,13 +47,9 @@ static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts,
if (CGOpts.DisableLifetimeMarkers)
return false;
// Disable lifetime markers in msan builds.
// FIXME: Remove this when msan works with lifetime markers.
if (LangOpts.Sanitize.has(SanitizerKind::Memory))
return false;
// Asan uses markers for use-after-scope checks.
if (CGOpts.SanitizeAddressUseAfterScope)
// Sanitizers may use markers.
if (CGOpts.SanitizeAddressUseAfterScope ||
LangOpts.Sanitize.has(SanitizerKind::Memory))
return true;
// For now, only in optimized builds.

View File

@ -2,6 +2,9 @@
// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - -O0 \
// RUN: -fsanitize=address -fsanitize-address-use-after-scope %s | \
// RUN: FileCheck %s -check-prefix=LIFETIME
// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - -O0 \
// RUN: -fsanitize=memory %s | \
// RUN: FileCheck %s -check-prefix=LIFETIME
extern int bar(char *A, int n);

View File

@ -3,6 +3,9 @@
// RUN: %clang -w -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 \
// RUN: -fsanitize=address -fsanitize-address-use-after-scope %s | \
// RUN: FileCheck %s -check-prefixes=CHECK,LIFETIME
// RUN: %clang -w -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 \
// RUN: -fsanitize=memory %s | \
// RUN: FileCheck %s -check-prefixes=CHECK,LIFETIME
extern int bar(char *A, int n);

View File

@ -0,0 +1,18 @@
// RUN: %clangxx_msan -O2 %s -o %t && \
// RUN: not %run %t 2>&1 | FileCheck %s
#include <stdlib.h>
int *p;
int main() {
for (int i = 0; i < 3; i++) {
int x;
if (i == 0)
x = 0;
p = &x;
}
return *p; // BOOM
// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
// CHECK: #0 0x{{.*}} in main {{.*}}loop-scope.cpp:[[@LINE-2]]
}

View File

@ -3885,6 +3885,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
// Asan needs to poison memory to detect invalid access which is possible
// even for empty lifetime range.
if (II->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) ||
II->getFunction()->hasFnAttribute(Attribute::SanitizeMemory) ||
II->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress))
break;

View File

@ -34,6 +34,21 @@ entry:
ret void
}
define void @msan() sanitize_memory {
entry:
; CHECK-LABEL: @msan(
%text = alloca i8, align 1
call void @llvm.lifetime.start.p0i8(i64 1, i8* %text)
call void @llvm.lifetime.end.p0i8(i64 1, i8* %text)
; CHECK: call void @llvm.lifetime.start
; CHECK-NEXT: call void @llvm.lifetime.end
call void @foo(i8* %text) ; Keep alloca alive
ret void
}
define void @no_asan() {
entry:
; CHECK-LABEL: @no_asan(