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
diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp
index 4d7a4d9..d2a2dd6 100644
--- a/lib/Analysis/BasicObjCFoundationChecks.cpp
+++ b/lib/Analysis/BasicObjCFoundationChecks.cpp
@@ -32,16 +32,18 @@
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 @@
virtual ~BasicObjCFoundationChecks() {}
virtual bool Audit(ExplodedNode<ValueState>* N);
+
+ virtual void ReportResults(Diagnostic& D);
+
};
} // end anonymous namespace
@@ -98,6 +103,10 @@
return false;
}
+static inline bool isNil(RVal X) {
+ return isa<lval::ConcreteInt>(X);
+}
+
//===----------------------------------------------------------------------===//
// Error reporting.
//===----------------------------------------------------------------------===//
@@ -110,6 +119,26 @@
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 @@
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;