forked from OSchip/llvm-project
Added lval type (and tracking) for StringLiterals.
llvm-svn: 50109
This commit is contained in:
parent
eccf3e5821
commit
c79c0591d6
|
@ -151,6 +151,8 @@ public:
|
|||
|
||||
static LVal MakeVal(AddrLabelExpr* E);
|
||||
|
||||
static LVal MakeVal(StringLiteral* S);
|
||||
|
||||
// Implement isa<T> support.
|
||||
static inline bool classof(const RVal* V) {
|
||||
return V->getBaseKind() == LValKind;
|
||||
|
@ -274,7 +276,7 @@ public:
|
|||
namespace lval {
|
||||
|
||||
enum Kind { SymbolValKind, GotoLabelKind, DeclValKind, FuncValKind,
|
||||
ConcreteIntKind };
|
||||
ConcreteIntKind, StringLiteralValKind };
|
||||
|
||||
class SymbolVal : public LVal {
|
||||
public:
|
||||
|
@ -391,6 +393,24 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class StringLiteralVal : public LVal {
|
||||
public:
|
||||
StringLiteralVal(StringLiteral* L) : LVal(StringLiteralValKind, L) {}
|
||||
|
||||
StringLiteral* getLiteral() const { return (StringLiteral*) Data; }
|
||||
|
||||
// Implement isa<T> support.
|
||||
static inline bool classof(const RVal* V) {
|
||||
return V->getBaseKind() == LValKind &&
|
||||
V->getSubKind() == StringLiteralValKind;
|
||||
}
|
||||
|
||||
static inline bool classof(const LVal* V) {
|
||||
return V->getSubKind() == StringLiteralValKind;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // end clang::lval namespace
|
||||
} // end clang namespace
|
||||
|
||||
|
|
|
@ -826,6 +826,8 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
|
|||
// should compose behavior, not copy it.
|
||||
StateMgr.Unbind(StVals, cast<LVal>(V));
|
||||
}
|
||||
else if (isa<nonlval::LValAsInteger>(V))
|
||||
StateMgr.Unbind(StVals, cast<nonlval::LValAsInteger>(V).getLVal());
|
||||
}
|
||||
|
||||
St = StateMgr.getPersistentState(StVals);
|
||||
|
|
|
@ -2014,6 +2014,7 @@ ValueState* GRExprEngine::AssumeAux(ValueState* St, LVal Cond,
|
|||
case lval::DeclValKind:
|
||||
case lval::FuncValKind:
|
||||
case lval::GotoLabelKind:
|
||||
case lval::StringLiteralValKind:
|
||||
isFeasible = Assumption;
|
||||
return St;
|
||||
|
||||
|
|
|
@ -572,6 +572,10 @@ void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
|
|||
|
||||
if (isa<LVal>(V))
|
||||
St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
|
||||
else if (isa<nonlval::LValAsInteger>(V))
|
||||
St = StateMgr.SetRVal(St, cast<nonlval::LValAsInteger>(V).getLVal(),
|
||||
UnknownVal());
|
||||
|
||||
}
|
||||
|
||||
// Make up a symbol for the return value of this function.
|
||||
|
|
|
@ -240,6 +240,10 @@ RVal RVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
|
|||
|
||||
LVal LVal::MakeVal(AddrLabelExpr* E) { return lval::GotoLabel(E->getLabel()); }
|
||||
|
||||
LVal LVal::MakeVal(StringLiteral* S) {
|
||||
return lval::StringLiteralVal(S);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Utility methods for constructing RVals (both NonLVals and LVals).
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -392,6 +396,12 @@ void LVal::print(std::ostream& Out) const {
|
|||
<< cast<lval::FuncVal>(this)->getDecl()->getIdentifier()->getName();
|
||||
break;
|
||||
|
||||
case lval::StringLiteralValKind:
|
||||
Out << "literal \""
|
||||
<< cast<lval::StringLiteralVal>(this)->getLiteral()->getStrData()
|
||||
<< "\"";
|
||||
break;
|
||||
|
||||
default:
|
||||
assert (false && "Pretty-printing not implemented for this LVal.");
|
||||
break;
|
||||
|
|
|
@ -265,6 +265,9 @@ RVal ValueStateManager::GetRVal(ValueState* St, Expr* E) {
|
|||
return NonLVal::MakeVal(BasicVals, cast<IntegerLiteral>(E));
|
||||
}
|
||||
|
||||
case Stmt::StringLiteralClass:
|
||||
return LVal::MakeVal(cast<StringLiteral>(E));
|
||||
|
||||
// Casts where the source and target type are the same
|
||||
// are no-ops. We blast through these to get the descendant
|
||||
// subexpression that has a value.
|
||||
|
|
|
@ -39,3 +39,10 @@ int f4(int *p) {
|
|||
int *q = (int*) x;
|
||||
return *q; // expected-warning{{Dereference of null pointer.}}
|
||||
}
|
||||
|
||||
int f5() {
|
||||
|
||||
char *s = "hello world";
|
||||
return s[0]; // no-warning
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue