aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Analysis/CFRefCount.cpp6
-rw-r--r--Analysis/GRExprEngine.cpp23
-rw-r--r--Analysis/GRSimpleVals.cpp2
-rw-r--r--Analysis/SymbolManager.cpp12
-rw-r--r--include/clang/Analysis/PathSensitive/SymbolManager.h24
5 files changed, 43 insertions, 24 deletions
diff --git a/Analysis/CFRefCount.cpp b/Analysis/CFRefCount.cpp
index 6c5493c206..c87ca673b9 100644
--- a/Analysis/CFRefCount.cpp
+++ b/Analysis/CFRefCount.cpp
@@ -588,7 +588,7 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
if (CE->getType() != Eng.getContext().VoidTy) {
unsigned Count = Builder.getCurrentBlockCount();
- SymbolID Sym = Eng.getSymbolManager().getCallRetValSymbol(CE, Count);
+ SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);
RVal X = CE->getType()->isPointerType()
? cast<RVal>(lval::SymbolVal(Sym))
@@ -664,7 +664,7 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
case RetEffect::OwnedSymbol: {
unsigned Count = Builder.getCurrentBlockCount();
- SymbolID Sym = Eng.getSymbolManager().getCallRetValSymbol(CE, Count);
+ SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);
ValueState StImpl = *St;
RefBindings B = GetRefBindings(StImpl);
@@ -679,7 +679,7 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
case RetEffect::NotOwnedSymbol: {
unsigned Count = Builder.getCurrentBlockCount();
- SymbolID Sym = Eng.getSymbolManager().getCallRetValSymbol(CE, Count);
+ SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);
ValueState StImpl = *St;
RefBindings B = GetRefBindings(StImpl);
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp
index 61643a440e..b8892e3ee5 100644
--- a/Analysis/GRExprEngine.cpp
+++ b/Analysis/GRExprEngine.cpp
@@ -177,7 +177,7 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term,
// Process the true branch.
- bool isFeasible = true;
+ bool isFeasible = false;
ValueState* St = Assume(PrevState, V, true, isFeasible);
if (isFeasible)
@@ -300,8 +300,8 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
RVal Res = EvalBinOp(BinaryOperator::EQ, CondV, CaseVal);
// Now "assume" that the case matches.
- bool isFeasible = false;
+ bool isFeasible = false;
ValueState* StNew = Assume(St, Res, true, isFeasible);
if (isFeasible) {
@@ -317,6 +317,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
// Now "assume" that the case doesn't match. Add this state
// to the default state (if it is feasible).
+ isFeasible = false;
StNew = Assume(DefaultSt, Res, false, isFeasible);
if (isFeasible)
@@ -1114,10 +1115,27 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
continue;
}
+ // EXPERIMENTAL: "Conjured" symbols.
+
+ if (RightV.isUnknown()) {
+ unsigned Count = Builder->getCurrentBlockCount();
+ SymbolID Sym = SymMgr.getConjuredSymbol(B->getRHS(), Count);
+
+ RightV = B->getRHS()->getType()->isPointerType()
+ ? cast<RVal>(lval::SymbolVal(Sym))
+ : cast<RVal>(nonlval::SymbolVal(Sym));
+ }
+
+ // Even if the LHS evaluates to an unknown L-Value, the entire
+ // expression still evaluates to the RHS.
+
if (LeftV.isUnknown()) {
St = SetRVal(St, B, RightV);
break;
}
+
+ // Simulate the effects of a "store": bind the value of the RHS
+ // to the L-Value represented by the LHS.
St = SetRVal(SetRVal(St, B, RightV), cast<LVal>(LeftV), RightV);
break;
@@ -1531,6 +1549,7 @@ GRExprEngine::AssumeSymInt(ValueState* St, bool Assumption,
switch (C.getOpcode()) {
default:
// No logic yet for other operators.
+ isFeasible = true;
return St;
case BinaryOperator::EQ:
diff --git a/Analysis/GRSimpleVals.cpp b/Analysis/GRSimpleVals.cpp
index b4abc3afdd..a03303c079 100644
--- a/Analysis/GRSimpleVals.cpp
+++ b/Analysis/GRSimpleVals.cpp
@@ -432,7 +432,7 @@ void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
if (CE->getType() != Eng.getContext().VoidTy) {
unsigned Count = Builder.getCurrentBlockCount();
- SymbolID Sym = Eng.getSymbolManager().getCallRetValSymbol(CE, Count);
+ SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);
RVal X = CE->getType()->isPointerType()
? cast<RVal>(lval::SymbolVal(Sym))
diff --git a/Analysis/SymbolManager.cpp b/Analysis/SymbolManager.cpp
index 5454649443..f243fa667b 100644
--- a/Analysis/SymbolManager.cpp
+++ b/Analysis/SymbolManager.cpp
@@ -72,10 +72,10 @@ SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) {
return SymbolCounter++;
}
-SymbolID SymbolManager::getCallRetValSymbol(CallExpr* CE, unsigned Count) {
+SymbolID SymbolManager::getConjuredSymbol(Expr* E, unsigned Count) {
llvm::FoldingSetNodeID profile;
- SymbolDataCallRetVal::Profile(profile, CE, Count);
+ SymbolConjured::Profile(profile, E, Count);
void* InsertPos;
SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
@@ -83,8 +83,8 @@ SymbolID SymbolManager::getCallRetValSymbol(CallExpr* CE, unsigned Count) {
if (SD)
return SD->getSymbol();
- SD = (SymbolData*) BPAlloc.Allocate<SymbolDataCallRetVal>();
- new (SD) SymbolDataCallRetVal(SymbolCounter, CE, Count);
+ SD = (SymbolData*) BPAlloc.Allocate<SymbolConjured>();
+ new (SD) SymbolConjured(SymbolCounter, E, Count);
DataSet.InsertNode(SD, InsertPos);
DataMap[SymbolCounter] = SD;
@@ -116,8 +116,8 @@ QualType SymbolData::getType(const SymbolManager& SymMgr) const {
return T->getAsPointerType()->getPointeeType();
}
- case CallRetValKind:
- return cast<SymbolDataCallRetVal>(this)->getCallExpr()->getType();
+ case ConjuredKind:
+ return cast<SymbolConjured>(this)->getExpr()->getType();
}
}
diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h
index a740302c8d..d0473c6a8e 100644
--- a/include/clang/Analysis/PathSensitive/SymbolManager.h
+++ b/include/clang/Analysis/PathSensitive/SymbolManager.h
@@ -69,7 +69,7 @@ namespace clang {
class SymbolData : public llvm::FoldingSetNode {
public:
- enum Kind { UndefKind, ParmKind, GlobalKind, ContentsOfKind, CallRetValKind };
+ enum Kind { UndefKind, ParmKind, GlobalKind, ContentsOfKind, ConjuredKind };
private:
Kind K;
@@ -165,32 +165,32 @@ public:
}
};
-class SymbolDataCallRetVal : public SymbolData {
- CallExpr* CE;
+class SymbolConjured : public SymbolData {
+ Expr* E;
unsigned Count;
public:
- SymbolDataCallRetVal(SymbolID Sym, CallExpr* ce, unsigned count)
- : SymbolData(CallRetValKind, Sym), CE(ce), Count(count) {}
+ SymbolConjured(SymbolID Sym, Expr* exp, unsigned count)
+ : SymbolData(ConjuredKind, Sym), E(exp), Count(count) {}
- CallExpr* getCallExpr() const { return CE; }
+ Expr* getExpr() const { return E; }
unsigned getCount() const { return Count; }
static void Profile(llvm::FoldingSetNodeID& profile,
- CallExpr* CE, unsigned Count) {
+ Expr* E, unsigned Count) {
- profile.AddInteger((unsigned) CallRetValKind);
- profile.AddPointer(CE);
+ profile.AddInteger((unsigned) ConjuredKind);
+ profile.AddPointer(E);
profile.AddInteger(Count);
}
virtual void Profile(llvm::FoldingSetNodeID& profile) {
- Profile(profile, CE, Count);
+ Profile(profile, E, Count);
}
// Implement isa<T> support.
static inline bool classof(const SymbolData* D) {
- return D->getKind() == CallRetValKind;
+ return D->getKind() == ConjuredKind;
}
};
@@ -243,7 +243,7 @@ public:
SymbolID getSymbol(VarDecl* D);
SymbolID getContentsOfSymbol(SymbolID sym);
- SymbolID getCallRetValSymbol(CallExpr* CE, unsigned VisitCount);
+ SymbolID getConjuredSymbol(Expr* E, unsigned VisitCount);
const SymbolData& getSymbolData(SymbolID ID) const;