diff --git a/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 075a72f78b1..9a67cfc5a75 100644 --- a/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -427,6 +427,7 @@ struct MemorySanitizerVisitor : public InstVisitor { bool LoadShadow; bool PoisonStack; bool PoisonUndef; + bool CheckReturnValue; OwningPtr VAHelper; struct ShadowOriginAndInsertPoint { @@ -449,6 +450,9 @@ struct MemorySanitizerVisitor : public InstVisitor { LoadShadow = SanitizeFunction; PoisonStack = SanitizeFunction && ClPoisonStack; PoisonUndef = SanitizeFunction && ClPoisonUndef; + // FIXME: Consider using SpecialCaseList to specify a list of functions that + // must always return fully initialized values. For now, we hardcode "main". + CheckReturnValue = SanitizeFunction && (F.getName() == "main"); DEBUG(if (!InsertChecks) dbgs() << "MemorySanitizer is not inserting checks into '" @@ -1686,12 +1690,17 @@ struct MemorySanitizerVisitor : public InstVisitor { void visitReturnInst(ReturnInst &I) { IRBuilder<> IRB(&I); - if (Value *RetVal = I.getReturnValue()) { - // Set the shadow for the RetVal. - Value *Shadow = getShadow(RetVal); - Value *ShadowPtr = getShadowPtrForRetval(RetVal, IRB); - DEBUG(dbgs() << "Return: " << *Shadow << "\n" << *ShadowPtr << "\n"); + Value *RetVal = I.getReturnValue(); + if (!RetVal) return; + Value *ShadowPtr = getShadowPtrForRetval(RetVal, IRB); + if (CheckReturnValue) { + insertCheck(RetVal, &I); + Value *Shadow = getCleanShadow(RetVal); IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment); + } else { + Value *Shadow = getShadow(RetVal); + IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment); + // FIXME: make it conditional if ClStoreCleanOrigin==0 if (MS.TrackOrigins) IRB.CreateStore(getOrigin(RetVal), getOriginPtrForRetval(IRB)); } diff --git a/test/Instrumentation/MemorySanitizer/return_from_main.ll b/test/Instrumentation/MemorySanitizer/return_from_main.ll new file mode 100644 index 00000000000..81dc88834db --- /dev/null +++ b/test/Instrumentation/MemorySanitizer/return_from_main.ll @@ -0,0 +1,18 @@ +; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s +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" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @main() sanitize_memory { +entry: + %call = tail call i32 @f() + ret i32 %call +} + +declare i32 @f() sanitize_memory + +; CHECK: @main +; CHECK: call i32 @f() +; CHECK: store i32 0, {{.*}} @__msan_retval_tls +; CHECK: br i1 +; CHECK: call void @__msan_warning_noreturn() +; CHECK: ret i32