From: Ted Kremenek Date: Tue, 12 Feb 2008 21:37:56 +0000 (+0000) Subject: Added transfer function/value track logic for taking the address of a label. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2a502578a785d5e7ed9e08e2895dbdcfa5333c11;p=clang Added transfer function/value track logic for taking the address of a label. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47030 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Analysis/RValues.cpp b/Analysis/RValues.cpp index f4b8a3d340..5f361eebf8 100644 --- a/Analysis/RValues.cpp +++ b/Analysis/RValues.cpp @@ -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: @@ -577,6 +585,11 @@ void LValue::print(std::ostream& Out) const { case lval::SymbolValKind: Out << '$' << cast(this)->getSymbol(); break; + + case lval::GotoLabelKind: + Out << "&&" + << cast(this)->getLabel()->getID()->getName(); + break; case lval::DeclValKind: Out << '&' diff --git a/Analysis/RValues.h b/Analysis/RValues.h index 9aa2f11e19..ffc5e4a57d 100644 --- a/Analysis/RValues.h +++ b/Analysis/RValues.h @@ -364,6 +364,8 @@ public: RValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const; + static LValue GetValue(AddrLabelExpr* E); + // Implement isa 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 }; @@ -460,9 +463,31 @@ namespace lval { static inline bool classof(const RValue* V) { return isa(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(getRawPtr()); + } + + static inline bool classof(const RValue* V) { + return isa(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(V) && V->getSubKind() == DeclValKind; } + + static inline bool classof(const LValue* V) { + return V->getSubKind() == DeclValKind; + } }; class ConcreteInt : public LValue { @@ -510,8 +539,7 @@ namespace lval { }; } // end clang::lval namespace - - + } // end clang namespace #endif diff --git a/Analysis/ValueState.cpp b/Analysis/ValueState.cpp index d550716fd5..c74c876b51 100644 --- a/Analysis/ValueState.cpp +++ b/Analysis/ValueState.cpp @@ -168,6 +168,9 @@ ValueStateManager::AddEQ(ValueState St, SymbolID sym, const llvm::APSInt& V) { RValue ValueStateManager::GetValue(ValueState St, Expr* E, bool* hasVal) { for (;;) { switch (E->getStmtClass()) { + + case Stmt::AddrLabelExprClass: + return LValue::GetValue(cast(E)); // ParenExprs are no-ops.