forked from OSchip/llvm-project
parent
cfc40ef98a
commit
e1a5a1f7a8
|
@ -1,9 +1,16 @@
|
||||||
// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t >%t.out 2>&1
|
// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t >%t.out 2>&1
|
||||||
// RUN: %clangxx_msan -m64 -O1 %s -o %t && %run %t >%t.out 2>&1
|
// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1
|
||||||
// RUN: %clangxx_msan -m64 -O2 %s -o %t && %run %t >%t.out 2>&1
|
// RUN: FileCheck %s < %t.out
|
||||||
// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t >%t.out 2>&1
|
// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1
|
||||||
|
// RUN: FileCheck %s < %t.out
|
||||||
|
// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1
|
||||||
|
// RUN: FileCheck %s < %t.out
|
||||||
|
|
||||||
// Test that (no_sanitize_memory) functions DO NOT propagate shadow.
|
// Test that (no_sanitize_memory) functions propagate shadow.
|
||||||
|
|
||||||
|
// Note that at -O0 there is no report, because 'x' in 'f' is spilled to the
|
||||||
|
// stack, and then loaded back as a fully initialiazed value (due to
|
||||||
|
// no_sanitize_memory attribute).
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -18,6 +25,8 @@ int main(void) {
|
||||||
int x;
|
int x;
|
||||||
int * volatile p = &x;
|
int * volatile p = &x;
|
||||||
int y = f(*p);
|
int y = f(*p);
|
||||||
|
// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
|
||||||
|
// CHECK: {{#0 0x.* in main .*no_sanitize_memory_prop.cc:}}[[@LINE+1]]
|
||||||
if (y)
|
if (y)
|
||||||
exit(0);
|
exit(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -511,7 +511,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||||
// The following flags disable parts of MSan instrumentation based on
|
// The following flags disable parts of MSan instrumentation based on
|
||||||
// blacklist contents and command-line options.
|
// blacklist contents and command-line options.
|
||||||
bool InsertChecks;
|
bool InsertChecks;
|
||||||
bool PropagateShadow;
|
bool LoadShadow;
|
||||||
bool PoisonStack;
|
bool PoisonStack;
|
||||||
bool PoisonUndef;
|
bool PoisonUndef;
|
||||||
bool CheckReturnValue;
|
bool CheckReturnValue;
|
||||||
|
@ -532,7 +532,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||||
bool SanitizeFunction = F.getAttributes().hasAttribute(
|
bool SanitizeFunction = F.getAttributes().hasAttribute(
|
||||||
AttributeSet::FunctionIndex, Attribute::SanitizeMemory);
|
AttributeSet::FunctionIndex, Attribute::SanitizeMemory);
|
||||||
InsertChecks = SanitizeFunction;
|
InsertChecks = SanitizeFunction;
|
||||||
PropagateShadow = SanitizeFunction;
|
LoadShadow = SanitizeFunction;
|
||||||
PoisonStack = SanitizeFunction && ClPoisonStack;
|
PoisonStack = SanitizeFunction && ClPoisonStack;
|
||||||
PoisonUndef = SanitizeFunction && ClPoisonUndef;
|
PoisonUndef = SanitizeFunction && ClPoisonUndef;
|
||||||
// FIXME: Consider using SpecialCaseList to specify a list of functions that
|
// FIXME: Consider using SpecialCaseList to specify a list of functions that
|
||||||
|
@ -716,14 +716,13 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||||
|
|
||||||
// Finalize PHI nodes.
|
// Finalize PHI nodes.
|
||||||
for (PHINode *PN : ShadowPHINodes) {
|
for (PHINode *PN : ShadowPHINodes) {
|
||||||
Value *S = getShadow(PN);
|
|
||||||
if (isa<Constant>(S)) continue;
|
|
||||||
PHINode *PNS = cast<PHINode>(getShadow(PN));
|
PHINode *PNS = cast<PHINode>(getShadow(PN));
|
||||||
PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : nullptr;
|
PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : nullptr;
|
||||||
size_t NumValues = PN->getNumIncomingValues();
|
size_t NumValues = PN->getNumIncomingValues();
|
||||||
for (size_t v = 0; v < NumValues; v++) {
|
for (size_t v = 0; v < NumValues; v++) {
|
||||||
PNS->addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
|
PNS->addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
|
||||||
if (PNO) PNO->addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
|
if (PNO)
|
||||||
|
PNO->addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -857,7 +856,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||||
/// \brief Set SV to be the shadow value for V.
|
/// \brief Set SV to be the shadow value for V.
|
||||||
void setShadow(Value *V, Value *SV) {
|
void setShadow(Value *V, Value *SV) {
|
||||||
assert(!ShadowMap.count(V) && "Values may only have one shadow");
|
assert(!ShadowMap.count(V) && "Values may only have one shadow");
|
||||||
ShadowMap[V] = PropagateShadow ? SV : getCleanShadow(V);
|
ShadowMap[V] = SV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Set Origin to be the origin value for V.
|
/// \brief Set Origin to be the origin value for V.
|
||||||
|
@ -909,7 +908,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||||
/// This function either returns the value set earlier with setShadow,
|
/// This function either returns the value set earlier with setShadow,
|
||||||
/// or extracts if from ParamTLS (for function arguments).
|
/// or extracts if from ParamTLS (for function arguments).
|
||||||
Value *getShadow(Value *V) {
|
Value *getShadow(Value *V) {
|
||||||
if (!PropagateShadow) return getCleanShadow(V);
|
|
||||||
if (Instruction *I = dyn_cast<Instruction>(V)) {
|
if (Instruction *I = dyn_cast<Instruction>(V)) {
|
||||||
// For instructions the shadow is already stored in the map.
|
// For instructions the shadow is already stored in the map.
|
||||||
Value *Shadow = ShadowMap[V];
|
Value *Shadow = ShadowMap[V];
|
||||||
|
@ -1077,7 +1075,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||||
IRBuilder<> IRB(I.getNextNode());
|
IRBuilder<> IRB(I.getNextNode());
|
||||||
Type *ShadowTy = getShadowTy(&I);
|
Type *ShadowTy = getShadowTy(&I);
|
||||||
Value *Addr = I.getPointerOperand();
|
Value *Addr = I.getPointerOperand();
|
||||||
if (PropagateShadow) {
|
if (LoadShadow) {
|
||||||
Value *ShadowPtr = getShadowPtr(Addr, ShadowTy, IRB);
|
Value *ShadowPtr = getShadowPtr(Addr, ShadowTy, IRB);
|
||||||
setShadow(&I,
|
setShadow(&I,
|
||||||
IRB.CreateAlignedLoad(ShadowPtr, I.getAlignment(), "_msld"));
|
IRB.CreateAlignedLoad(ShadowPtr, I.getAlignment(), "_msld"));
|
||||||
|
@ -1092,7 +1090,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||||
I.setOrdering(addAcquireOrdering(I.getOrdering()));
|
I.setOrdering(addAcquireOrdering(I.getOrdering()));
|
||||||
|
|
||||||
if (MS.TrackOrigins) {
|
if (MS.TrackOrigins) {
|
||||||
if (PropagateShadow) {
|
if (LoadShadow) {
|
||||||
unsigned Alignment = std::max(kMinOriginAlignment, I.getAlignment());
|
unsigned Alignment = std::max(kMinOriginAlignment, I.getAlignment());
|
||||||
setOrigin(&I,
|
setOrigin(&I,
|
||||||
IRB.CreateAlignedLoad(getOriginPtr(Addr, IRB), Alignment));
|
IRB.CreateAlignedLoad(getOriginPtr(Addr, IRB), Alignment));
|
||||||
|
@ -1759,7 +1757,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||||
Value *Addr = I.getArgOperand(0);
|
Value *Addr = I.getArgOperand(0);
|
||||||
|
|
||||||
Type *ShadowTy = getShadowTy(&I);
|
Type *ShadowTy = getShadowTy(&I);
|
||||||
if (PropagateShadow) {
|
if (LoadShadow) {
|
||||||
Value *ShadowPtr = getShadowPtr(Addr, ShadowTy, IRB);
|
Value *ShadowPtr = getShadowPtr(Addr, ShadowTy, IRB);
|
||||||
// We don't know the pointer alignment (could be unaligned SSE load!).
|
// We don't know the pointer alignment (could be unaligned SSE load!).
|
||||||
// Have to assume to worst case.
|
// Have to assume to worst case.
|
||||||
|
@ -1772,7 +1770,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||||
insertShadowCheck(Addr, &I);
|
insertShadowCheck(Addr, &I);
|
||||||
|
|
||||||
if (MS.TrackOrigins) {
|
if (MS.TrackOrigins) {
|
||||||
if (PropagateShadow)
|
if (LoadShadow)
|
||||||
setOrigin(&I, IRB.CreateLoad(getOriginPtr(Addr, IRB)));
|
setOrigin(&I, IRB.CreateLoad(getOriginPtr(Addr, IRB)));
|
||||||
else
|
else
|
||||||
setOrigin(&I, getCleanOrigin());
|
setOrigin(&I, getCleanOrigin());
|
||||||
|
|
Loading…
Reference in New Issue