diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 20 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 39 | ||||
-rw-r--r-- | lib/Analysis/UndefinedArgChecker.cpp | 40 |
3 files changed, 34 insertions, 65 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 2b4b5ae1a5..047e27dabd 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -1998,26 +1998,6 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME, } } - // Check for any arguments that are uninitialized/undefined. - - for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end(); - I != E; ++I) { - - if (state->getSVal(*I).isUndef()) { - - // Generate an error node for passing an uninitialized/undefined value - // as an argument to a message expression. This node is a sink. - ExplodedNode* N = Builder->generateNode(ME, state, Pred); - - if (N) { - N->markAsSink(); - MsgExprUndefArgs[N] = *I; - } - - return; - } - } - // Handle previsits checks. ExplodedNodeSet Src, DstTmp; Src.Add(Pred); diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp index d0f60fde5b..50e855fda9 100644 --- a/lib/Analysis/GRExprEngineInternalChecks.cpp +++ b/lib/Analysis/GRExprEngineInternalChecks.cpp @@ -34,11 +34,6 @@ ExplodedNode* GetNode(ITERATOR I) { return *I; } -template <> inline -ExplodedNode* GetNode(GRExprEngine::undef_arg_iterator I) { - return I->first; -} - //===----------------------------------------------------------------------===// // Bug Descriptions. //===----------------------------------------------------------------------===// @@ -224,39 +219,6 @@ public: const Stmt *getArg() const { return Arg; } }; -class VISIBILITY_HIDDEN BadArg : public BuiltinBug { -public: - BadArg(GRExprEngine* eng=0) : BuiltinBug(eng,"Uninitialized argument", - "Pass-by-value argument in function call is undefined") {} - - BadArg(GRExprEngine* eng, const char* d) - : BuiltinBug(eng,"Uninitialized argument", d) {} - - void registerInitialVisitors(BugReporterContext& BRC, - const ExplodedNode* N, - BuiltinBugReport *R) { - registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(), - N); - } -}; - -class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg { -public: - BadMsgExprArg(GRExprEngine* eng) - : BadArg(eng,"Pass-by-value argument in message expression is undefined"){} - - void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) { - for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(), - E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) { - // Generate a report for this bug. - ArgReport *report = new ArgReport(*this, desc.c_str(), I->first, - I->second); - report->addRange(I->second->getSourceRange()); - BR.EmitReport(report); - } - } -}; - class VISIBILITY_HIDDEN BadReceiver : public BuiltinBug { public: BadReceiver(GRExprEngine* eng) @@ -375,7 +337,6 @@ void GRExprEngine::RegisterInternalChecks() { // to 'FlushReports' from BugReporter. BR.Register(new UndefBranch(this)); BR.Register(new UndefResult(this)); - BR.Register(new BadMsgExprArg(this)); BR.Register(new BadReceiver(this)); BR.Register(new NilReceiverStructRet(this)); BR.Register(new NilReceiverLargerThanVoidPtrRet(this)); diff --git a/lib/Analysis/UndefinedArgChecker.cpp b/lib/Analysis/UndefinedArgChecker.cpp index 923a7e1bed..a0c0d48712 100644 --- a/lib/Analysis/UndefinedArgChecker.cpp +++ b/lib/Analysis/UndefinedArgChecker.cpp @@ -21,14 +21,16 @@ using namespace clang; namespace { class VISIBILITY_HIDDEN UndefinedArgChecker : public CheckerVisitor<UndefinedArgChecker> { - BugType *BT; + BugType *BT_call; + BugType *BT_msg; public: - UndefinedArgChecker() : BT(0) {} + UndefinedArgChecker() : BT_call(0), BT_msg(0) {} static void *getTag() { static int x = 0; return &x; } void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE); + void PreVisitObjCMessageExpr(CheckerContext &C, const ObjCMessageExpr *ME); }; } // end anonymous namespace @@ -42,14 +44,40 @@ void UndefinedArgChecker::PreVisitCallExpr(CheckerContext &C, I != E; ++I) { if (C.getState()->getSVal(*I).isUndef()) { if (ExplodedNode *N = C.GenerateNode(CE, true)) { - if (!BT) - BT = new BuiltinBug("Pass-by-value argument in function call is " - "undefined"); + if (!BT_call) + BT_call = new BuiltinBug("Pass-by-value argument in function call is " + "undefined"); // Generate a report for this bug. - EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getName(), N); + EnhancedBugReport *R = new EnhancedBugReport(*BT_call, + BT_call->getName(), N); R->addRange((*I)->getSourceRange()); R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, *I); C.EmitReport(R); + return; + } + } + } +} + +void UndefinedArgChecker::PreVisitObjCMessageExpr(CheckerContext &C, + const ObjCMessageExpr *ME) { + + // Check for any arguments that are uninitialized/undefined. + const GRState *state = C.getState(); + for (ObjCMessageExpr::const_arg_iterator I = ME->arg_begin(), E = ME->arg_end(); + I != E; ++I) { + if (state->getSVal(*I).isUndef()) { + if (ExplodedNode *N = C.GenerateNode(ME, true)) { + if (!BT_msg) + BT_msg = new BuiltinBug("Pass-by-value argument in message expression" + " is undefined"); + // Generate a report for this bug. + EnhancedBugReport *R = new EnhancedBugReport(*BT_msg, BT_msg->getName(), + N); + R->addRange((*I)->getSourceRange()); + R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, *I); + C.EmitReport(R); + return; } } } |