summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp7
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp10
-rw-r--r--clang/test/CodeGen/lifetime-sanitizer.c3
-rw-r--r--clang/test/CodeGenCXX/lifetime-sanitizer.cpp3
-rw-r--r--compiler-rt/test/msan/loop-scope.cpp18
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp1
-rw-r--r--llvm/test/Transforms/InstCombine/lifetime-sanitizer.ll15
7 files changed, 46 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d53fb46f336..0e04a514565 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -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;
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 95b8fdce783..228093044e1 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -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.
diff --git a/clang/test/CodeGen/lifetime-sanitizer.c b/clang/test/CodeGen/lifetime-sanitizer.c
index 7979c2679a9..04714d7a19c 100644
--- a/clang/test/CodeGen/lifetime-sanitizer.c
+++ b/clang/test/CodeGen/lifetime-sanitizer.c
@@ -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);
diff --git a/clang/test/CodeGenCXX/lifetime-sanitizer.cpp b/clang/test/CodeGenCXX/lifetime-sanitizer.cpp
index 8b6cb7dcc05..7921483eeee 100644
--- a/clang/test/CodeGenCXX/lifetime-sanitizer.cpp
+++ b/clang/test/CodeGenCXX/lifetime-sanitizer.cpp
@@ -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);
diff --git a/compiler-rt/test/msan/loop-scope.cpp b/compiler-rt/test/msan/loop-scope.cpp
new file mode 100644
index 00000000000..638bdbe1732
--- /dev/null
+++ b/compiler-rt/test/msan/loop-scope.cpp
@@ -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]]
+}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 4b3333affa7..1802e8c8780 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -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;
diff --git a/llvm/test/Transforms/InstCombine/lifetime-sanitizer.ll b/llvm/test/Transforms/InstCombine/lifetime-sanitizer.ll
index e7b996def82..4b3cad1b965 100644
--- a/llvm/test/Transforms/InstCombine/lifetime-sanitizer.ll
+++ b/llvm/test/Transforms/InstCombine/lifetime-sanitizer.ll
@@ -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(
OpenPOWER on IntegriCloud