summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp')
-rw-r--r--gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp174
1 files changed, 0 insertions, 174 deletions
diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
deleted file mode 100644
index 34ce47823d5..00000000000
--- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-//== ObjCContainersASTChecker.cpp - CoreFoundation containers API *- C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// An AST checker that looks for common pitfalls when using 'CFArray',
-// 'CFDictionary', 'CFSet' APIs.
-//
-//===----------------------------------------------------------------------===//
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/Analysis/AnalysisDeclContext.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
-#include "clang/StaticAnalyzer/Core/Checker.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-using namespace ento;
-
-namespace {
-class WalkAST : public StmtVisitor<WalkAST> {
- BugReporter &BR;
- const CheckerBase *Checker;
- AnalysisDeclContext* AC;
- ASTContext &ASTC;
- uint64_t PtrWidth;
-
- /// Check if the type has pointer size (very conservative).
- inline bool isPointerSize(const Type *T) {
- if (!T)
- return true;
- if (T->isIncompleteType())
- return true;
- return (ASTC.getTypeSize(T) == PtrWidth);
- }
-
- /// Check if the type is a pointer/array to pointer sized values.
- inline bool hasPointerToPointerSizedType(const Expr *E) {
- QualType T = E->getType();
-
- // The type could be either a pointer or array.
- const Type *TP = T.getTypePtr();
- QualType PointeeT = TP->getPointeeType();
- if (!PointeeT.isNull()) {
- // If the type is a pointer to an array, check the size of the array
- // elements. To avoid false positives coming from assumption that the
- // values x and &x are equal when x is an array.
- if (const Type *TElem = PointeeT->getArrayElementTypeNoTypeQual())
- if (isPointerSize(TElem))
- return true;
-
- // Else, check the pointee size.
- return isPointerSize(PointeeT.getTypePtr());
- }
-
- if (const Type *TElem = TP->getArrayElementTypeNoTypeQual())
- return isPointerSize(TElem);
-
- // The type must be an array/pointer type.
-
- // This could be a null constant, which is allowed.
- return static_cast<bool>(
- E->isNullPointerConstant(ASTC, Expr::NPC_ValueDependentIsNull));
- }
-
-public:
- WalkAST(BugReporter &br, const CheckerBase *checker, AnalysisDeclContext *ac)
- : BR(br), Checker(checker), AC(ac), ASTC(AC->getASTContext()),
- PtrWidth(ASTC.getTargetInfo().getPointerWidth(0)) {}
-
- // Statement visitor methods.
- void VisitChildren(Stmt *S);
- void VisitStmt(Stmt *S) { VisitChildren(S); }
- void VisitCallExpr(CallExpr *CE);
-};
-} // end anonymous namespace
-
-static StringRef getCalleeName(CallExpr *CE) {
- const FunctionDecl *FD = CE->getDirectCallee();
- if (!FD)
- return StringRef();
-
- IdentifierInfo *II = FD->getIdentifier();
- if (!II) // if no identifier, not a simple C function
- return StringRef();
-
- return II->getName();
-}
-
-void WalkAST::VisitCallExpr(CallExpr *CE) {
- StringRef Name = getCalleeName(CE);
- if (Name.empty())
- return;
-
- const Expr *Arg = nullptr;
- unsigned ArgNum;
-
- if (Name.equals("CFArrayCreate") || Name.equals("CFSetCreate")) {
- if (CE->getNumArgs() != 4)
- return;
- ArgNum = 1;
- Arg = CE->getArg(ArgNum)->IgnoreParenCasts();
- if (hasPointerToPointerSizedType(Arg))
- return;
- } else if (Name.equals("CFDictionaryCreate")) {
- if (CE->getNumArgs() != 6)
- return;
- // Check first argument.
- ArgNum = 1;
- Arg = CE->getArg(ArgNum)->IgnoreParenCasts();
- if (hasPointerToPointerSizedType(Arg)) {
- // Check second argument.
- ArgNum = 2;
- Arg = CE->getArg(ArgNum)->IgnoreParenCasts();
- if (hasPointerToPointerSizedType(Arg))
- // Both are good, return.
- return;
- }
- }
-
- if (Arg) {
- assert(ArgNum == 1 || ArgNum == 2);
-
- SmallString<64> BufName;
- llvm::raw_svector_ostream OsName(BufName);
- OsName << " Invalid use of '" << Name << "'" ;
-
- SmallString<256> Buf;
- llvm::raw_svector_ostream Os(Buf);
- // Use "second" and "third" since users will expect 1-based indexing
- // for parameter names when mentioned in prose.
- Os << " The "<< ((ArgNum == 1) ? "second" : "third") << " argument to '"
- << Name << "' must be a C array of pointer-sized values, not '"
- << Arg->getType().getAsString() << "'";
-
- PathDiagnosticLocation CELoc =
- PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
- BR.EmitBasicReport(AC->getDecl(), Checker, OsName.str(),
- categories::CoreFoundationObjectiveC, Os.str(), CELoc,
- Arg->getSourceRange());
- }
-
- // Recurse and check children.
- VisitChildren(CE);
-}
-
-void WalkAST::VisitChildren(Stmt *S) {
- for (Stmt *Child : S->children())
- if (Child)
- Visit(Child);
-}
-
-namespace {
-class ObjCContainersASTChecker : public Checker<check::ASTCodeBody> {
-public:
-
- void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr,
- BugReporter &BR) const {
- WalkAST walker(BR, this, Mgr.getAnalysisDeclContext(D));
- walker.Visit(D->getBody());
- }
-};
-}
-
-void ento::registerObjCContainersASTChecker(CheckerManager &mgr) {
- mgr.registerChecker<ObjCContainersASTChecker>();
-}