diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -1672,9 +1672,8 @@ /// This function either returns the value set earlier with setShadow, /// or extracts if from ParamTLS (for function arguments). Value *getShadow(Value *V) { - if (!PropagateShadow) return getCleanShadow(V); if (Instruction *I = dyn_cast(V)) { - if (I->getMetadata("nosanitize")) + if (!PropagateShadow || I->getMetadata("nosanitize")) return getCleanShadow(V); // For instructions the shadow is already stored in the map. Value *Shadow = ShadowMap[V]; @@ -1686,7 +1685,8 @@ return Shadow; } if (UndefValue *U = dyn_cast(V)) { - Value *AllOnes = PoisonUndef ? getPoisonedShadow(V) : getCleanShadow(V); + Value *AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V) + : getCleanShadow(V); LLVM_DEBUG(dbgs() << "Undef: " << *U << " ==> " << *AllOnes << "\n"); (void)U; return AllOnes; @@ -1723,7 +1723,7 @@ /*isStore*/ true) .first; // TODO(glider): need to copy origins. - if (Overflow) { + if (!PropagateShadow || Overflow) { // ParamTLS overflow. EntryIRB.CreateMemSet( CpShadowPtr, Constant::getNullValue(EntryIRB.getInt8Ty()), @@ -1738,7 +1738,7 @@ } } - if (Overflow || FArg.hasByValAttr() || + if (!PropagateShadow || Overflow || FArg.hasByValAttr() || (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) { *ShadowPtr = getCleanShadow(V); setOrigin(A, getCleanOrigin()); diff --git a/llvm/test/Instrumentation/MemorySanitizer/byval.ll b/llvm/test/Instrumentation/MemorySanitizer/byval.ll --- a/llvm/test/Instrumentation/MemorySanitizer/byval.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/byval.ll @@ -26,6 +26,7 @@ define i128 @ByValArgumentNoSanitize(i32, i128* byval(i128) %p) { ; CHECK-LABEL: @ByValArgumentNoSanitize( ; CHECK-NEXT: entry: +; CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 {{.*}}, i8 0, i64 16, i1 false) ; CHECK: %x = load i128, i128* %p ; CHECK: store i128 0, i128* bitcast ([100 x i64]* @__msan_retval_tls to i128*) ; CHECK-NEXT: store i32 0, i32* @__msan_retval_origin_tls @@ -50,10 +51,10 @@ ret void } -; FIXME: Shadow of byval pointee is copied but not reset. define void @ByValForwardNoSanitize(i32, i128* byval(i128) %p) { ; CHECK-LABEL: @ByValForwardNoSanitize( ; CHECK-NEXT: entry: +; CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 {{.*}}, i8 0, i64 16, i1 false) ; CHECK: store i64 0, i64* getelementptr inbounds ([100 x i64], [100 x i64]* @__msan_param_tls, i32 0, i32 0) ; CHECK-NEXT: call void @Fn( ; CHECK-NEXT: ret void @@ -78,10 +79,11 @@ ret void } -; FIXME: Shadow of byval pointee is copied but not reset. +; FIXME: Shadow for byval should be reset not copied before the call. define void @ByValForwardByValNoSanitize(i32, i128* byval(i128) %p) { ; CHECK-LABEL: @ByValForwardByValNoSanitize( ; CHECK-NEXT: entry: +; CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 {{.*}}, i8 0, i64 16, i1 false) ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast ([100 x i64]* @__msan_param_tls to i8*), i8* {{.*}}, i64 16, i1 false) ; CHECK: store i32 0, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__msan_param_origin_tls, i32 0, i32 0) ; CHECK-NEXT: call void @FnByVal(