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))
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);
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);
// Process the true branch.
- bool isFeasible = true;
+ bool isFeasible = false;
ValueState* St = Assume(PrevState, V, true, isFeasible);
if (isFeasible)
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) {
// 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)
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;
switch (C.getOpcode()) {
default:
// No logic yet for other operators.
+ isFeasible = true;
return St;
case BinaryOperator::EQ:
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))
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);
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;
return T->getAsPointerType()->getPointeeType();
}
- case CallRetValKind:
- return cast<SymbolDataCallRetVal>(this)->getCallExpr()->getType();
+ case ConjuredKind:
+ return cast<SymbolConjured>(this)->getExpr()->getType();
}
}
class SymbolData : public llvm::FoldingSetNode {
public:
- enum Kind { UndefKind, ParmKind, GlobalKind, ContentsOfKind, CallRetValKind };
+ enum Kind { UndefKind, ParmKind, GlobalKind, ContentsOfKind, ConjuredKind };
private:
Kind K;
}
};
-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;
}
};
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;