aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Instrumentation/MemorySanitizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Instrumentation/MemorySanitizer.cpp')
-rw-r--r--lib/Transforms/Instrumentation/MemorySanitizer.cpp13
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;