r184288 - Fix a crash in the static analyzer (bug #16307)
Pavel Labath
labath at google.com
Wed Jun 19 01:19:57 PDT 2013
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}}
+ }
+}
More information about the cfe-commits
mailing list