]> granicus.if.org Git - clang/commitdiff
Teach RegionStore::EnterStackFrame() to handle
authorTed Kremenek <kremenek@apple.com>
Fri, 14 Jan 2011 20:29:43 +0000 (20:29 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 14 Jan 2011 20:29:43 +0000 (20:29 +0000)
the case where the called function has fewer
formal arguments than actual arguments.  This
fixes a crash in the analyzer when doing
function call inlining.

Patch by Zhenbo Xu!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123458 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/RegionStore.cpp
test/Analysis/inline.c

index 58cec303132991080b3588de95ec1578fae980b7..0dbf97caf945e8650969d365250f166f18e363cc 100644 (file)
@@ -1868,17 +1868,20 @@ Store RegionStoreManager::RemoveDeadBindings(Store store,
 Store RegionStoreManager::EnterStackFrame(const GRState *state,
                                           const StackFrameContext *frame) {
   FunctionDecl const *FD = cast<FunctionDecl>(frame->getDecl());
-  FunctionDecl::param_const_iterator PI = FD->param_begin();
+  FunctionDecl::param_const_iterator PI = FD->param_begin(), 
+                                     PE = FD->param_end();
   Store store = state->getStore();
 
   if (CallExpr const *CE = dyn_cast<CallExpr>(frame->getCallSite())) {
     CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end();
 
-    // Copy the arg expression value to the arg variables.
-    for (; AI != AE; ++AI, ++PI) {
+    // Copy the arg expression value to the arg variables.  We check that
+    // PI != PE because the actual number of arguments may be different than
+    // the function declaration.
+    for (; AI != AE && PI != PE; ++AI, ++PI) {
       SVal ArgVal = state->getSVal(*AI);
       store = Bind(store,
-                   svalBuilder.makeLoc(MRMgr.getVarRegion(*PI,frame)), ArgVal);
+                   svalBuilder.makeLoc(MRMgr.getVarRegion(*PI, frame)), ArgVal);
     }
   } else if (const CXXConstructExpr *CE =
                dyn_cast<CXXConstructExpr>(frame->getCallSite())) {
index 50c1a54d1016c3f95380c94257616869ad8b64b8..d7a599a76545a369a22195dc86f6f9dd043fc4ed 100644 (file)
@@ -1,14 +1,14 @@
 // RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-inline-call -analyzer-store region -verify %s
 
-int f1() {
+int test1_f1() {
   int y = 1;
   y++;
   return y;
 }
 
-void f2() {
+void test1_f2() {
   int x = 1;
-  x = f1();
+  x = test1_f1();
   if (x == 1) {
     int *p = 0;
     *p = 3; // no-warning
@@ -18,3 +18,13 @@ void f2() {
     *p = 3; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}}
   }
 }
+
+// Test that inlining works when the declared function has less arguments
+// than the actual number in the declaration.
+void test2_f1() {}
+int test2_f2();
+
+void test2_f3() { 
+  test2_f1(test2_f2()); // expected-warning{{too many arguments in call to 'test2_f1'}}
+}
+