r287001 - [analyzer] Add check for when block is called with too few arguments.
Devin Coughlin via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 15 10:40:46 PST 2016
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)}}
}
More information about the cfe-commits
mailing list