diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-03-27 21:15:17 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-03-27 21:15:17 +0000 |
commit | e5d5c204c761cc3b2a6374a15b035420f207c7af (patch) | |
tree | 3a17ff2a287a423e6685351aa3639b522fb000bf /lib/Analysis/BasicObjCFoundationChecks.cpp | |
parent | 0f9063c116b7c3b05d8042b5976463c2dae04861 (diff) |
Hooked up initial NSString interface checking to GRSimpleVals.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48895 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/BasicObjCFoundationChecks.cpp')
-rw-r--r-- | lib/Analysis/BasicObjCFoundationChecks.cpp | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp index 4d7a4d99db..d2a2dd6a51 100644 --- a/lib/Analysis/BasicObjCFoundationChecks.cpp +++ b/lib/Analysis/BasicObjCFoundationChecks.cpp @@ -32,16 +32,18 @@ namespace { class VISIBILITY_HIDDEN BasicObjCFoundationChecks : public GRSimpleAPICheck { - ASTContext &Ctx; - ValueStateManager* VMgr; - std::list<AnnotatedPath<ValueState> > Errors; + ASTContext &Ctx; + ValueStateManager* VMgr; + + typedef std::list<AnnotatedPath<ValueState> > ErrorsTy; + ErrorsTy Errors; - RVal GetRVal(ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); } + RVal GetRVal(ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); } - bool isNSString(ObjCInterfaceType* T, const char* suffix); - bool AuditNSString(NodeTy* N, ObjCMessageExpr* ME); + bool isNSString(ObjCInterfaceType* T, const char* suffix); + bool AuditNSString(NodeTy* N, ObjCMessageExpr* ME); - void RegisterError(NodeTy* N, Expr* E, const char *msg); + void RegisterError(NodeTy* N, Expr* E, const char *msg); public: BasicObjCFoundationChecks(ASTContext& ctx, ValueStateManager* vmgr) @@ -50,6 +52,9 @@ public: virtual ~BasicObjCFoundationChecks() {} virtual bool Audit(ExplodedNode<ValueState>* N); + + virtual void ReportResults(Diagnostic& D); + }; } // end anonymous namespace @@ -98,6 +103,10 @@ bool BasicObjCFoundationChecks::Audit(ExplodedNode<ValueState>* N) { return false; } +static inline bool isNil(RVal X) { + return isa<lval::ConcreteInt>(X); +} + //===----------------------------------------------------------------------===// // Error reporting. //===----------------------------------------------------------------------===// @@ -110,6 +119,26 @@ void BasicObjCFoundationChecks::RegisterError(NodeTy* N, Errors.back().push_back(N, msg, E); } +void BasicObjCFoundationChecks::ReportResults(Diagnostic& D) { + + // FIXME: Expand errors into paths. For now, just issue warnings. + + for (ErrorsTy::iterator I=Errors.begin(), E=Errors.end(); I!=E; ++I) { + + AnnotatedNode<ValueState>& AN = I->back(); + + unsigned diag = D.getCustomDiagID(Diagnostic::Warning, + AN.getString().c_str()); + + Stmt* S = cast<PostStmt>(AN.getNode()->getLocation()).getStmt(); + FullSourceLoc L(S->getLocStart(), Ctx.getSourceManager()); + + SourceRange R = AN.getExpr()->getSourceRange(); + + D.Report(diag, &AN.getString(), 1, &R, 1); + } +} + //===----------------------------------------------------------------------===// // NSString checking. //===----------------------------------------------------------------------===// @@ -139,10 +168,9 @@ bool BasicObjCFoundationChecks::AuditNSString(NodeTy* N, Expr * E = ME->getArg(0); RVal X = GetRVal(St, E); - if (isa<lval::ConcreteInt>(X)) { + if (isNil(X)) RegisterError(N, E, "Argument to NSString method 'compare:' cannot be nil."); - } } return false; |