27 using namespace clang;
31 class ObjCContainersChecker :
public Checker< check::PreStmt<CallExpr>,
32 check::PostStmt<CallExpr>,
33 check::PointerEscape> {
34 mutable std::unique_ptr<BugType> BT;
35 inline void initBugType()
const {
37 BT.reset(
new BugType(
this,
"CFArray API",
47 void addSizeInfo(
const Expr *Array,
const Expr *Size,
52 static void *getTag() {
static int Tag;
return &Tag; }
66 void ObjCContainersChecker::addSizeInfo(const
Expr *Array, const
Expr *Size,
69 SVal SizeV = State->getSVal(Size, C.getLocationContext());
75 SVal ArrayRef = State->getSVal(Array, C.getLocationContext());
85 void ObjCContainersChecker::checkPostStmt(
const CallExpr *CE,
92 if (Name.equals(
"CFArrayCreate")) {
98 addSizeInfo(CE, CE->
getArg(2),
C);
102 if (Name.equals(
"CFArrayGetCount")) {
103 addSizeInfo(CE->
getArg(0), CE,
C);
108 void ObjCContainersChecker::checkPreStmt(
const CallExpr *CE,
115 if (Name.equals(
"CFArrayGetValueAtIndex")) {
121 SymbolRef ArraySym = getArraySym(ArrayExpr, C);
125 const DefinedSVal *Size = State->get<ArraySizeMap>(ArraySym);
140 ProgramStateRef StOutBound = State->assumeInBound(Idx, *Size,
false, T);
141 if (StOutBound && !StInBound) {
146 auto R = llvm::make_unique<BugReport>(*BT,
"Index is out of bounds", N);
147 R->addRange(IdxExpr->getSourceRange());
159 for (InvalidatedSymbols::const_iterator
I = Escaped.begin(),
168 State = State->remove<ArraySizeMap>(Sym);
const char *const CoreFoundationObjectiveC
StringRef getCalleeName(const FunctionDecl *FunDecl) const
Get the name of the called function (path-sensitive).
A (possibly-)qualified type.
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
bool isUnknownOrUndef() const
detail::InMemoryDirectory::const_iterator I
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
Expr - This represents one expression.
const ProgramStateRef & getState() const
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
detail::InMemoryDirectory::const_iterator E
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Represents an abstract call to a function or method along a particular path.
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
const LocationContext * getLocationContext() const