Author: dcoughlin Date: Tue Nov 15 12:40:46 2016 New Revision: 287001 URL: http://llvm.org/viewvc/llvm-project?rev=287001&view=rev Log: [analyzer] Add check for when block is called with too few arguments.
The CallAndMessageChecker has an existing check for when a function pointer is called with too few arguments. Extend this logic to handle the block case, as well. While we're at it, do a drive-by grammar correction ("less" --> "fewer") on the diagnostic text. Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp cfe/trunk/test/Analysis/blocks.m cfe/trunk/test/Analysis/inline.c cfe/trunk/test/Analysis/inline.cpp cfe/trunk/test/Analysis/nullability.c Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=287001&r1=287000&r2=287001&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Tue Nov 15 12:40:46 2016 @@ -356,7 +356,6 @@ void CallAndMessageChecker::checkPreStmt } } - void CallAndMessageChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); @@ -389,11 +388,10 @@ void CallAndMessageChecker::checkPreCall } const Decl *D = Call.getDecl(); - const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D); - if (FD) { - // If we have a declaration, we can make sure we pass enough parameters to - // the function. - unsigned Params = FD->getNumParams(); + if (D && (isa<FunctionDecl>(D) || isa<BlockDecl>(D))) { + // If we have a function or block declaration, we can make sure we pass + // enough parameters. + unsigned Params = Call.parameters().size(); if (Call.getNumArgs() < Params) { ExplodedNode *N = C.generateErrorNode(); if (!N) @@ -403,8 +401,14 @@ void CallAndMessageChecker::checkPreCall SmallString<512> Str; llvm::raw_svector_ostream os(Str); - os << "Function taking " << Params << " argument" - << (Params == 1 ? "" : "s") << " is called with less (" + if (isa<FunctionDecl>(D)) { + os << "Function "; + } else { + assert(isa<BlockDecl>(D)); + os << "Block "; + } + os << "taking " << Params << " argument" + << (Params == 1 ? "" : "s") << " is called with fewer (" << Call.getNumArgs() << ")"; C.emitReport( @@ -425,6 +429,7 @@ void CallAndMessageChecker::checkPreCall else BT = &BT_call_arg; + const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D); for (unsigned i = 0, e = Call.getNumArgs(); i != e; ++i) { const ParmVarDecl *ParamDecl = nullptr; if(FD && i < FD->getNumParams()) Modified: cfe/trunk/test/Analysis/blocks.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/blocks.m?rev=287001&r1=287000&r2=287001&view=diff ============================================================================== --- cfe/trunk/test/Analysis/blocks.m (original) +++ cfe/trunk/test/Analysis/blocks.m Tue Nov 15 12:40:46 2016 @@ -232,3 +232,12 @@ __attribute__((objc_root_class)) }); } @end + +// The incorrect block variable initialization below is a hard compile-time +// error in C++. +#if !defined(__cplusplus) +void call_block_with_fewer_arguments() { + void (^b)() = ^(int a) { }; + b(); // expected-warning {{Block taking 1 argument is called with fewer (0)}} +} +#endif Modified: cfe/trunk/test/Analysis/inline.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.c?rev=287001&r1=287000&r2=287001&view=diff ============================================================================== --- cfe/trunk/test/Analysis/inline.c (original) +++ cfe/trunk/test/Analysis/inline.c Tue Nov 15 12:40:46 2016 @@ -114,5 +114,5 @@ void never_called_by_anyone() { 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}} + knr_one_argument(); // expected-warning{{too few arguments}} expected-warning{{Function taking 1 argument is called with fewer (0)}} } Modified: cfe/trunk/test/Analysis/inline.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.cpp?rev=287001&r1=287000&r2=287001&view=diff ============================================================================== --- cfe/trunk/test/Analysis/inline.cpp (original) +++ cfe/trunk/test/Analysis/inline.cpp Tue Nov 15 12:40:46 2016 @@ -441,6 +441,6 @@ namespace rdar12409977 { namespace bug16307 { void one_argument(int a) { } void call_with_less() { - reinterpret_cast<void (*)()>(one_argument)(); // expected-warning{{Function taking 1 argument}} + reinterpret_cast<void (*)()>(one_argument)(); // expected-warning{{Function taking 1 argument is called with fewer (0)}} } } Modified: cfe/trunk/test/Analysis/nullability.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/nullability.c?rev=287001&r1=287000&r2=287001&view=diff ============================================================================== --- cfe/trunk/test/Analysis/nullability.c (original) +++ cfe/trunk/test/Analysis/nullability.c Tue Nov 15 12:40:46 2016 @@ -3,10 +3,10 @@ void it_takes_two(int a, int b); void function_pointer_arity_mismatch() { void(*fptr)() = it_takes_two; - fptr(1); // no-crash expected-warning {{Function taking 2 arguments is called with less (1)}} + fptr(1); // no-crash expected-warning {{Function taking 2 arguments is called with fewer (1)}} } void block_arity_mismatch() { - void(^b)() = ^(int a, int b) { }; // no-crash - b(1); + void(^b)() = ^(int a, int b) { }; + b(1); // no-crash expected-warning {{Block taking 2 arguments is called with fewer (1)}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits