Author: labath Date: Wed Jun 19 03:19:56 2013 New Revision: 184288 URL: http://llvm.org/viewvc/llvm-project?rev=184288&view=rev Log: Fix a crash in the static analyzer (bug #16307)
Summary: When processing a call to a function, which got passed less arguments than it expects, the analyzer would crash. I've also added a test for that and a analyzer warning which detects these cases. CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D994 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp cfe/trunk/test/Analysis/inline.c cfe/trunk/test/Analysis/inline.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=184288&r1=184287&r2=184288&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Wed Jun 19 03:19:56 2013 @@ -40,6 +40,7 @@ class CallAndMessageChecker mutable OwningPtr<BugType> BT_objc_subscript_undef; mutable OwningPtr<BugType> BT_msg_arg; mutable OwningPtr<BugType> BT_msg_ret; + mutable OwningPtr<BugType> BT_call_few_args; public: void checkPreStmt(const CallExpr *CE, CheckerContext &C) const; @@ -280,11 +281,33 @@ void CallAndMessageChecker::checkPreCall State = StNonNull; } + const Decl *D = Call.getDecl(); + if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { + // If we have a declaration, we can make sure we pass enough parameters to + // the function. + unsigned Params = FD->getNumParams(); + if (Call.getNumArgs() < Params) { + ExplodedNode *N = C.generateSink(); + if (!N) + return; + + LazyInit_BT("Function call with too few arguments", BT_call_few_args); + + SmallString<512> Str; + llvm::raw_svector_ostream os(Str); + os << "Function taking " << Params << " argument" + << (Params == 1 ? "" : "s") << " is called with less (" + << Call.getNumArgs() << ")"; + + BugReport *R = new BugReport(*BT_call_few_args, os.str(), N); + C.emitReport(R); + } + } + // Don't check for uninitialized field values in arguments if the // caller has a body that is available and we have the chance to inline it. // This is a hack, but is a reasonable compromise betweens sometimes warning // and sometimes not depending on if we decide to inline a function. - const Decl *D = Call.getDecl(); const bool checkUninitFields = !(C.getAnalysisManager().shouldInlineCall() && (D && D->getBody())); Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=184288&r1=184287&r2=184288&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Wed Jun 19 03:19:56 2013 @@ -272,8 +272,11 @@ static void addParameterValuesToBindings CallEvent::param_iterator E) { MemRegionManager &MRMgr = SVB.getRegionManager(); + // If the function has fewer parameters than the call has arguments, we simply + // do not bind any values to them. + unsigned NumArgs = Call.getNumArgs(); unsigned Idx = 0; - for (; I != E; ++I, ++Idx) { + for (; I != E && Idx < NumArgs; ++I, ++Idx) { const ParmVarDecl *ParamDecl = *I; assert(ParamDecl && "Formal parameter has no decl?"); Modified: cfe/trunk/test/Analysis/inline.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.c?rev=184288&r1=184287&r2=184288&view=diff ============================================================================== --- cfe/trunk/test/Analysis/inline.c (original) +++ cfe/trunk/test/Analysis/inline.c Wed Jun 19 03:19:56 2013 @@ -110,3 +110,9 @@ void never_called_by_anyone() { clang_analyzer_checkInlined(0); // no-warning } + +void knr_one_argument(a) int a; { } + +void call_with_less_arguments() { + knr_one_argument(); // expected-warning{{too few arguments}} expected-warning{{Function taking 1 argument}} +} Modified: cfe/trunk/test/Analysis/inline.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.cpp?rev=184288&r1=184287&r2=184288&view=diff ============================================================================== --- cfe/trunk/test/Analysis/inline.cpp (original) +++ cfe/trunk/test/Analysis/inline.cpp Wed Jun 19 03:19:56 2013 @@ -420,3 +420,10 @@ namespace rdar12409977 { clang_analyzer_eval(obj.getThis()->x == 42); // expected-warning{{TRUE}} } } + +namespace bug16307 { + void one_argument(int a) { } + void call_with_less() { + reinterpret_cast<void (*)()>(one_argument)(); // expected-warning{{Function taking 1 argument}} + } +} _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
