BasicObjCFoundationChecks.cpp revision 4ba6283f9c7db4513ca2d9cbde7df3a58ba941f7
199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek//== BasicObjCFoundationChecks.cpp - Simple Apple-Foundation checks -*- C++ -*-- 299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// 399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// The LLVM Compiler Infrastructure 499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// 599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// This file is distributed under the University of Illinois Open Source 699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// License. See LICENSE.TXT for details. 799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// 899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek//===----------------------------------------------------------------------===// 999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// 1099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// This file defines BasicObjCFoundationChecks, a class that encapsulates 1199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// a set of simple checks to run on Objective-C code using Apple's Foundation 1299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// classes. 1399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// 1499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek//===----------------------------------------------------------------------===// 1599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 16527556184b276c545be1355ad596fce29a0400fbTed Kremenek#include "BasicObjCFoundationChecks.h" 17527556184b276c545be1355ad596fce29a0400fbTed Kremenek 1899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek#include "clang/Analysis/PathSensitive/ExplodedGraph.h" 1999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h" 2099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek#include "clang/Analysis/PathSensitive/ValueState.h" 2199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek#include "clang/Analysis/PathSensitive/AnnotatedPath.h" 2299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek#include "clang/Analysis/PathDiagnostic.h" 2399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek#include "clang/AST/Expr.h" 2499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek#include "clang/AST/ASTContext.h" 2599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek#include "llvm/Support/Compiler.h" 2699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 2799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek#include <vector> 284ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek#include <sstream> 2999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 3099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenekusing namespace clang; 3199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 3299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremeneknamespace { 3399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 3499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenekclass VISIBILITY_HIDDEN BasicObjCFoundationChecks : public GRSimpleAPICheck { 3599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 36e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek ASTContext &Ctx; 37e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek ValueStateManager* VMgr; 38e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 39e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek typedef std::list<AnnotatedPath<ValueState> > ErrorsTy; 40e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek ErrorsTy Errors; 4199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 42e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek RVal GetRVal(ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); } 4399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 44e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek bool isNSString(ObjCInterfaceType* T, const char* suffix); 45e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek bool AuditNSString(NodeTy* N, ObjCMessageExpr* ME); 4699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 474ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek void Warn(NodeTy* N, Expr* E, const std::string& s); 484ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek void WarnNilArg(NodeTy* N, Expr* E); 494ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 504ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek bool CheckNilArg(NodeTy* N, unsigned Arg); 5199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 5299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenekpublic: 5399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek BasicObjCFoundationChecks(ASTContext& ctx, ValueStateManager* vmgr) 5499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek : Ctx(ctx), VMgr(vmgr) {} 5599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 5699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek virtual ~BasicObjCFoundationChecks() {} 5799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 5899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek virtual bool Audit(ExplodedNode<ValueState>* N); 59e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 60e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek virtual void ReportResults(Diagnostic& D); 61e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 6299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek}; 6399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 6499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek} // end anonymous namespace 6599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 6699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 67527556184b276c545be1355ad596fce29a0400fbTed KremenekGRSimpleAPICheck* 68527556184b276c545be1355ad596fce29a0400fbTed Kremenekclang::CreateBasicObjCFoundationChecks(ASTContext& Ctx, 69527556184b276c545be1355ad596fce29a0400fbTed Kremenek ValueStateManager* VMgr) { 70527556184b276c545be1355ad596fce29a0400fbTed Kremenek 71527556184b276c545be1355ad596fce29a0400fbTed Kremenek return new BasicObjCFoundationChecks(Ctx, VMgr); 72527556184b276c545be1355ad596fce29a0400fbTed Kremenek} 73527556184b276c545be1355ad596fce29a0400fbTed Kremenek 744ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenekstatic ObjCInterfaceType* GetReceiverType(ObjCMessageExpr* ME) { 7599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek Expr* Receiver = ME->getReceiver(); 7699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 7799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek if (!Receiver) 784ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return NULL; 7999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 8099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek assert (Receiver->getType()->isPointerType()); 814ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 8299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek const PointerType* T = Receiver->getType()->getAsPointerType(); 834ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 844ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return dyn_cast<ObjCInterfaceType>(T->getPointeeType().getTypePtr()); 854ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek} 864ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 874ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenekstatic const char* GetReceiverNameType(ObjCMessageExpr* ME) { 884ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek ObjCInterfaceType* ReceiverType = GetReceiverType(ME); 894ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return ReceiverType ? ReceiverType->getDecl()->getIdentifier()->getName() 904ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek : NULL; 914ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek} 9299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 934ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenekbool BasicObjCFoundationChecks::Audit(ExplodedNode<ValueState>* N) { 944ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 954ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek ObjCMessageExpr* ME = 964ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt()); 974ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 984ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek ObjCInterfaceType* ReceiverType = GetReceiverType(ME); 9999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 10099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek if (!ReceiverType) 1014ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return NULL; 1024ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 1034ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek const char* name = ReceiverType->getDecl()->getIdentifier()->getName(); 10499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 1054ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek if (!name) 1064ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return false; 10799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 10899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek if (name[0] != 'N' || name[1] != 'S') 10999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek return false; 11099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 11199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek name += 2; 11299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 11399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek // FIXME: Make all of this faster. 11499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 11599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek if (isNSString(ReceiverType, name)) 11699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek return AuditNSString(N, ME); 11799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 11899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek return false; 11999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek} 12099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 121e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenekstatic inline bool isNil(RVal X) { 122e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek return isa<lval::ConcreteInt>(X); 123e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek} 124e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 12599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek//===----------------------------------------------------------------------===// 12699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// Error reporting. 12799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek//===----------------------------------------------------------------------===// 12899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 12999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 1304ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenekvoid BasicObjCFoundationChecks::Warn(NodeTy* N, Expr* E, const std::string& s) { 13199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek Errors.push_back(AnnotatedPath<ValueState>()); 1324ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek Errors.back().push_back(N, s, E); 13399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek} 13499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 135e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenekvoid BasicObjCFoundationChecks::ReportResults(Diagnostic& D) { 136e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 137e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek // FIXME: Expand errors into paths. For now, just issue warnings. 138e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 139e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek for (ErrorsTy::iterator I=Errors.begin(), E=Errors.end(); I!=E; ++I) { 140e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 141e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek AnnotatedNode<ValueState>& AN = I->back(); 142e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 143e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek unsigned diag = D.getCustomDiagID(Diagnostic::Warning, 144e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek AN.getString().c_str()); 145e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 146e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek Stmt* S = cast<PostStmt>(AN.getNode()->getLocation()).getStmt(); 147e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek FullSourceLoc L(S->getLocStart(), Ctx.getSourceManager()); 148e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 149e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek SourceRange R = AN.getExpr()->getSourceRange(); 150e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 1519b3fdeaca3660789d89e3980dc7d41e8676cd901Ted Kremenek D.Report(L, diag, &AN.getString(), 1, &R, 1); 152e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek } 153e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek} 154e5d5c204c761cc3b2a6374a15b035420f207c7afTed Kremenek 1554ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenekvoid BasicObjCFoundationChecks::WarnNilArg(NodeTy* N, Expr* E) { 1564ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 1574ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek ObjCMessageExpr* ME = 1584ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt()); 1594ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 1604ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek std::ostringstream os; 1614ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 1624ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek os << "Argument to '" << GetReceiverNameType(ME) << "' method '" 1634ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek << ME->getSelector().getName() 1644ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek << "' cannot be nil."; 1654ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 1664ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek Warn(N, E, os.str()); 1674ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek} 1684ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 1694ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenekbool BasicObjCFoundationChecks::CheckNilArg(NodeTy* N, unsigned Arg) { 1704ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek ObjCMessageExpr* ME = 1714ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt()); 1724ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 1734ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek Expr * E = ME->getArg(Arg); 1744ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 1754ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek if (isNil(GetRVal(N->getState(), E))) { 1764ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek WarnNilArg(N, E); 1774ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return true; 1784ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek } 1794ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 1804ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return false; 1814ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek} 1824ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 18399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek//===----------------------------------------------------------------------===// 18499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek// NSString checking. 18599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek//===----------------------------------------------------------------------===// 18699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 18799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenekbool BasicObjCFoundationChecks::isNSString(ObjCInterfaceType* T, 18899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek const char* suffix) { 18999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 19099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek return !strcmp("String", suffix) || !strcmp("MutableString", suffix); 19199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek} 19299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 19399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenekbool BasicObjCFoundationChecks::AuditNSString(NodeTy* N, 19499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek ObjCMessageExpr* ME) { 19599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 19699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek Selector S = ME->getSelector(); 19799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 19899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek if (S.isUnarySelector()) 19999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek return false; 20099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 20199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek // FIXME: This is going to be really slow doing these checks with 20299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek // lexical comparisons. 20399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 20499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek std::string name = S.getName(); 2059b3fdeaca3660789d89e3980dc7d41e8676cd901Ted Kremenek assert (!name.empty()); 2069b3fdeaca3660789d89e3980dc7d41e8676cd901Ted Kremenek const char* cstr = &name[0]; 2079b3fdeaca3660789d89e3980dc7d41e8676cd901Ted Kremenek unsigned len = name.size(); 2084ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2099b3fdeaca3660789d89e3980dc7d41e8676cd901Ted Kremenek switch (len) { 2109b3fdeaca3660789d89e3980dc7d41e8676cd901Ted Kremenek default: 2119b3fdeaca3660789d89e3980dc7d41e8676cd901Ted Kremenek break; 2129b3fdeaca3660789d89e3980dc7d41e8676cd901Ted Kremenek case 8: 2134ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2144ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek if (!strcmp(cstr, "compare:")) 2154ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return CheckNilArg(N, 0); 2164ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2174ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek break; 21899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 2194ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek case 16: 2204ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek if (!strcmp(cstr, "compare:options:")) 2214ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return CheckNilArg(N, 0); 2224ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2234ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek break; 2244ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2254ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek case 22: 2264ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek if (!strcmp(cstr, "compare:options:range:")) 2274ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return CheckNilArg(N, 0); 2284ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2294ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek break; 2304ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2314ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek case 23: 2324ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2334ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek if (!strcmp(cstr, "caseInsensitiveCompare:")) 2344ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return CheckNilArg(N, 0); 2359b3fdeaca3660789d89e3980dc7d41e8676cd901Ted Kremenek 2369b3fdeaca3660789d89e3980dc7d41e8676cd901Ted Kremenek break; 2374ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2384ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek case 29: 2394ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek if (!strcmp(cstr, "compare:options:range:locale:")) 2404ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return CheckNilArg(N, 0); 2414ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2424ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek break; 2434ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2444ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek case 37: 2454ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek if (!strcmp(cstr, "componentsSeparatedByCharactersInSet:")) 2464ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek return CheckNilArg(N, 0); 2474ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek 2484ba6283f9c7db4513ca2d9cbde7df3a58ba941f7Ted Kremenek break; 24999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek } 25099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 25199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek return false; 25299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek} 253