[msan] Remove readonly/readnone attributes from all called functions.
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Fri, 7 Dec 2012 09:08:32 +0000 (09:08 +0000)
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Fri, 7 Dec 2012 09:08:32 +0000 (09:08 +0000)
MSan uses a TLS slot to pass shadow for function arguments and return values.
This makes all instrumented functions not readonly, and at the same time
requires that all callees of an instrumented function that may be
MSan-instrumented do not have readonly attribute (otherwise some of the
instrumentation may be optimized out).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169591 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Instrumentation/MemorySanitizer.cpp

index a3b293eed6fea968ccb9fb0e0b613165a7a41fb8..65c894bee24e267300d2a85eb709ffb4a898e5f4 100644 (file)
@@ -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;