Added transfer function/value track logic for taking the address of a label.

llvm-svn: 47030
This commit is contained in:
Ted Kremenek 2008-02-12 21:37:56 +00:00
parent 1f3d4a73f5
commit 736e441266
3 changed files with 49 additions and 5 deletions

View File

@ -491,14 +491,22 @@ RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
return nonlval::SymbolVal(SymMgr.getSymbol(D));
}
void RValue::print() const {
print(*llvm::cerr.stream());
//===----------------------------------------------------------------------===//
// Utility methods for constructing LValues.
//===----------------------------------------------------------------------===//
LValue LValue::GetValue(AddrLabelExpr* E) {
return lval::GotoLabel(E->getLabel());
}
//===----------------------------------------------------------------------===//
// Pretty-Printing.
//===----------------------------------------------------------------------===//
void RValue::print() const {
print(*llvm::cerr.stream());
}
void RValue::print(std::ostream& Out) const {
switch (getBaseKind()) {
case UnknownKind:
@ -578,6 +586,11 @@ void LValue::print(std::ostream& Out) const {
Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
break;
case lval::GotoLabelKind:
Out << "&&"
<< cast<lval::GotoLabel>(this)->getLabel()->getID()->getName();
break;
case lval::DeclValKind:
Out << '&'
<< cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();

View File

@ -364,6 +364,8 @@ public:
RValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
static LValue GetValue(AddrLabelExpr* E);
// Implement isa<T> support.
static inline bool classof(const RValue* V) {
return V->getBaseKind() != NonLValueKind;
@ -445,6 +447,7 @@ namespace nonlval {
namespace lval {
enum Kind { SymbolValKind,
GotoLabelKind,
DeclValKind,
ConcreteIntKind,
NumKind };
@ -461,8 +464,30 @@ namespace lval {
static inline bool classof(const RValue* V) {
return isa<LValue>(V) && V->getSubKind() == SymbolValKind;
}
static inline bool classof(const LValue* V) {
return V->getSubKind() == SymbolValKind;
}
};
class GotoLabel : public LValue {
public:
GotoLabel(LabelStmt* Label) : LValue(GotoLabelKind, Label) {}
LabelStmt* getLabel() const {
return static_cast<LabelStmt*>(getRawPtr());
}
static inline bool classof(const RValue* V) {
return isa<LValue>(V) && V->getSubKind() == GotoLabelKind;
}
static inline bool classof(const LValue* V) {
return V->getSubKind() == GotoLabelKind;
}
};
class DeclVal : public LValue {
public:
DeclVal(const ValueDecl* vd) : LValue(DeclValKind,vd) {}
@ -483,6 +508,10 @@ namespace lval {
static inline bool classof(const RValue* V) {
return isa<LValue>(V) && V->getSubKind() == DeclValKind;
}
static inline bool classof(const LValue* V) {
return V->getSubKind() == DeclValKind;
}
};
class ConcreteInt : public LValue {
@ -511,7 +540,6 @@ namespace lval {
};
} // end clang::lval namespace
} // end clang namespace
#endif

View File

@ -169,6 +169,9 @@ RValue ValueStateManager::GetValue(ValueState St, Expr* E, bool* hasVal) {
for (;;) {
switch (E->getStmtClass()) {
case Stmt::AddrLabelExprClass:
return LValue::GetValue(cast<AddrLabelExpr>(E));
// ParenExprs are no-ops.
case Stmt::ParenExprClass: