[cfe-commits] r135255 - /cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
Ted Kremenek
kremenek at apple.com
Fri Jul 15 00:15:37 PDT 2011
Nice cleanup!
On Jul 14, 2011, at 11:29 PM, Jordy Rose wrote:
> Author: jrose
> Date: Fri Jul 15 01:28:59 2011
> New Revision: 135255
>
> URL: http://llvm.org/viewvc/llvm-project?rev=135255&view=rev
> Log:
> Clean up UnixAPIChecker, including switching its array of BugTypes to llvm::OwningPtr<BugType> vars (the new convention). No functionality change.
>
> Modified:
> cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp?rev=135255&r1=135254&r2=135255&view=diff
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp Fri Jul 15 01:28:59 2011
> @@ -28,26 +28,18 @@
>
> namespace {
> class UnixAPIChecker : public Checker< check::PreStmt<CallExpr> > {
> - enum SubChecks {
> - OpenFn = 0,
> - PthreadOnceFn = 1,
> - MallocZero = 2,
> - NumChecks
> - };
> -
> - mutable BugType *BTypes[NumChecks];
> -
> -public:
> + mutable llvm::OwningPtr<BugType> BT_open, BT_pthreadOnce, BT_mallocZero;
> mutable Optional<uint64_t> Val_O_CREAT;
>
> public:
> - UnixAPIChecker() { memset(BTypes, 0, sizeof(*BTypes) * NumChecks); }
> - ~UnixAPIChecker() {
> - for (unsigned i=0; i != NumChecks; ++i)
> - delete BTypes[i];
> - }
> -
> void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
> +
> + void CheckOpen(CheckerContext &C, const CallExpr *CE) const;
> + void CheckPthreadOnce(CheckerContext &C, const CallExpr *CE) const;
> + void CheckMallocZero(CheckerContext &C, const CallExpr *CE) const;
> +
> + typedef void (UnixAPIChecker::*SubChecker)(CheckerContext &,
> + const CallExpr *) const;
> };
> } //end anonymous namespace
>
> @@ -55,23 +47,23 @@
> // Utility functions.
> //===----------------------------------------------------------------------===//
>
> -static inline void LazyInitialize(BugType *&BT, const char *name) {
> +static inline void LazyInitialize(llvm::OwningPtr<BugType> &BT,
> + const char *name) {
> if (BT)
> return;
> - BT = new BugType(name, "Unix API");
> + BT.reset(new BugType(name, "Unix API"));
> }
>
> //===----------------------------------------------------------------------===//
> // "open" (man 2 open)
> //===----------------------------------------------------------------------===//
>
> -static void CheckOpen(CheckerContext &C, const UnixAPIChecker &UC,
> - const CallExpr *CE, BugType *&BT) {
> +void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
> // The definition of O_CREAT is platform specific. We need a better way
> // of querying this information from the checking environment.
> - if (!UC.Val_O_CREAT.hasValue()) {
> + if (!Val_O_CREAT.hasValue()) {
> if (C.getASTContext().Target.getTriple().getVendor() == llvm::Triple::Apple)
> - UC.Val_O_CREAT = 0x0200;
> + Val_O_CREAT = 0x0200;
> else {
> // FIXME: We need a more general way of getting the O_CREAT value.
> // We could possibly grovel through the preprocessor state, but
> @@ -80,8 +72,6 @@
> }
> }
>
> - LazyInitialize(BT, "Improper use of 'open'");
> -
> // Look at the 'oflags' argument for the O_CREAT flag.
> const GRState *state = C.getState();
>
> @@ -101,7 +91,7 @@
> }
> NonLoc oflags = cast<NonLoc>(V);
> NonLoc ocreateFlag =
> - cast<NonLoc>(C.getSValBuilder().makeIntVal(UC.Val_O_CREAT.getValue(),
> + cast<NonLoc>(C.getSValBuilder().makeIntVal(Val_O_CREAT.getValue(),
> oflagsEx->getType()));
> SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And,
> oflags, ocreateFlag,
> @@ -124,8 +114,10 @@
> if (!N)
> return;
>
> - EnhancedBugReport *report =
> - new EnhancedBugReport(*BT,
> + LazyInitialize(BT_open, "Improper use of 'open'");
> +
> + RangedBugReport *report =
> + new RangedBugReport(*BT_open,
> "Call to 'open' requires a third argument when "
> "the 'O_CREAT' flag is set", N);
> report->addRange(oflagsEx->getSourceRange());
> @@ -137,14 +129,12 @@
> // pthread_once
> //===----------------------------------------------------------------------===//
>
> -static void CheckPthreadOnce(CheckerContext &C, const UnixAPIChecker &,
> - const CallExpr *CE, BugType *&BT) {
> +void UnixAPIChecker::CheckPthreadOnce(CheckerContext &C,
> + const CallExpr *CE) const {
>
> // This is similar to 'CheckDispatchOnce' in the MacOSXAPIChecker.
> // They can possibly be refactored.
>
> - LazyInitialize(BT, "Improper use of 'pthread_once'");
> -
> if (CE->getNumArgs() < 1)
> return;
>
> @@ -171,7 +161,9 @@
> if (isa<VarRegion>(R) && isa<StackLocalsSpaceRegion>(R->getMemorySpace()))
> os << " Perhaps you intended to declare the variable as 'static'?";
>
> - EnhancedBugReport *report = new EnhancedBugReport(*BT, os.str(), N);
> + LazyInitialize(BT_pthreadOnce, "Improper use of 'pthread_once'");
> +
> + RangedBugReport *report = new RangedBugReport(*BT_pthreadOnce, os.str(), N);
> report->addRange(CE->getArg(0)->getSourceRange());
> C.EmitReport(report);
> }
> @@ -182,8 +174,8 @@
>
> // FIXME: Eventually this should be rolled into the MallocChecker, but this
> // check is more basic and is valuable for widespread use.
> -static void CheckMallocZero(CheckerContext &C, const UnixAPIChecker &UC,
> - const CallExpr *CE, BugType *&BT) {
> +void UnixAPIChecker::CheckMallocZero(CheckerContext &C,
> + const CallExpr *CE) const {
>
> // Sanity check that malloc takes one argument.
> if (CE->getNumArgs() != 1)
> @@ -208,11 +200,11 @@
> // FIXME: Add reference to CERT advisory, and/or C99 standard in bug
> // output.
>
> - LazyInitialize(BT, "Undefined allocation of 0 bytes");
> + LazyInitialize(BT_mallocZero, "Undefined allocation of 0 bytes");
>
> EnhancedBugReport *report =
> - new EnhancedBugReport(*BT, "Call to 'malloc' has an allocation size"
> - " of 0 bytes", N);
> + new EnhancedBugReport(*BT_mallocZero, "Call to 'malloc' has an allocation"
> + " size of 0 bytes", N);
> report->addRange(CE->getArg(0)->getSourceRange());
> report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
> CE->getArg(0));
> @@ -230,51 +222,29 @@
> // Central dispatch function.
> //===----------------------------------------------------------------------===//
>
> -typedef void (*SubChecker)(CheckerContext &C, const UnixAPIChecker &UC,
> - const CallExpr *CE, BugType *&BT);
> -namespace {
> - class SubCheck {
> - SubChecker SC;
> - const UnixAPIChecker *UC;
> - BugType **BT;
> - public:
> - SubCheck(SubChecker sc, const UnixAPIChecker *uc, BugType *& bt)
> - : SC(sc), UC(uc), BT(&bt) {}
> - SubCheck() : SC(NULL), UC(NULL), BT(NULL) {}
> -
> - void run(CheckerContext &C, const CallExpr *CE) const {
> - if (SC)
> - SC(C, *UC, CE, *BT);
> - }
> - };
> -} // end anonymous namespace
> -
> void UnixAPIChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
> // Get the callee. All the functions we care about are C functions
> // with simple identifiers.
> const GRState *state = C.getState();
> const Expr *Callee = CE->getCallee();
> - const FunctionTextRegion *Fn =
> - dyn_cast_or_null<FunctionTextRegion>(state->getSVal(Callee).getAsRegion());
> + const FunctionDecl *Fn = state->getSVal(Callee).getAsFunctionDecl();
>
> if (!Fn)
> return;
>
> - const IdentifierInfo *FI = Fn->getDecl()->getIdentifier();
> + const IdentifierInfo *FI = Fn->getIdentifier();
> if (!FI)
> return;
>
> - const SubCheck &SC =
> - llvm::StringSwitch<SubCheck>(FI->getName())
> - .Case("open",
> - SubCheck(CheckOpen, this, BTypes[OpenFn]))
> - .Case("pthread_once",
> - SubCheck(CheckPthreadOnce, this, BTypes[PthreadOnceFn]))
> - .Case("malloc",
> - SubCheck(CheckMallocZero, this, BTypes[MallocZero]))
> - .Default(SubCheck());
> + SubChecker SC =
> + llvm::StringSwitch<SubChecker>(FI->getName())
> + .Case("open", &UnixAPIChecker::CheckOpen)
> + .Case("pthread_once", &UnixAPIChecker::CheckPthreadOnce)
> + .Case("malloc", &UnixAPIChecker::CheckMallocZero)
> + .Default(NULL);
>
> - SC.run(C, CE);
> + if (SC)
> + (this->*SC)(C, CE);
> }
>
> //===----------------------------------------------------------------------===//
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list