diff options
Diffstat (limited to 'lib/Transforms/Instrumentation/MemorySanitizer.cpp')
-rw-r--r-- | lib/Transforms/Instrumentation/MemorySanitizer.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/lib/Transforms/Instrumentation/MemorySanitizer.cpp index a3b293eed6..65c894bee2 100644 --- a/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -1182,6 +1182,19 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { Call->setTailCall(false); assert(!isa<IntrinsicInst>(&I) && "intrinsics are handled elsewhere"); + + // We are going to insert code that relies on the fact that the callee + // will become a non-readonly function after it is instrumented by us. To + // prevent this code from being optimized out, mark that function + // non-readonly in advance. + if (Function *Func = Call->getCalledFunction()) { + // Clear out readonly/readnone attributes. + AttrBuilder B; + B.addAttribute(Attributes::ReadOnly) + .addAttribute(Attributes::ReadNone); + Func->removeAttribute(AttrListPtr::FunctionIndex, + Attributes::get(Func->getContext(), B)); + } } IRBuilder<> IRB(&I); unsigned ArgOffset = 0; |