danielmarjamaki created this revision.
danielmarjamaki added subscribers: cfe-commits, dcoughlin, NoQ.
danielmarjamaki set the repository for this revision to rL LLVM.

Returns when calling an inline function should not be merged in the 
ExplodedGraph unless they are same.

Background post on cfe-dev:
http://lists.llvm.org/pipermail/cfe-dev/2016-October/051001.html

Here is an example patch that solves my false positives and also fixes 2 false 
negatives in existing tests.

What do you think about this approach?


Repository:
  rL LLVM

https://reviews.llvm.org/D25326

Files:
  lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
  test/Analysis/inlining/InlineObjCClassMethod.m
  test/Analysis/unreachable-code-path.c


Index: test/Analysis/unreachable-code-path.c
===================================================================
--- test/Analysis/unreachable-code-path.c
+++ test/Analysis/unreachable-code-path.c
@@ -194,3 +194,14 @@
     break;
   }
 }
+
+extern int table[];
+static int inlineFunction(const int i) {
+  if (table[i] != 0) // <- SVal for table[0] is unknown
+    return 1;
+  return 0;
+}
+void test13(int i) {
+  int x = inlineFunction(i);
+  x && x < 10;
+}
Index: test/Analysis/inlining/InlineObjCClassMethod.m
===================================================================
--- test/Analysis/inlining/InlineObjCClassMethod.m
+++ test/Analysis/inlining/InlineObjCClassMethod.m
@@ -174,12 +174,12 @@
 @implementation MyClassSelf
 + (int)testClassMethodByKnownVarDecl {
   int y = [MyParentSelf testSelf];
-  return 5/y; // Should warn here.
+  return 5/y; // expected-warning{{Division by zero}}
 }
 @end
 int foo2() {
   int y = [MyParentSelf testSelf];
-  return 5/y; // Should warn here.
+  return 5/y; // expected-warning{{Division by zero}}
 }
 
 // TODO: We do not inline 'getNum' in the following case, where the value of 
Index: lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -23,6 +23,8 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/SaveAndRestore.h"
 
+REGISTER_TRAIT_WITH_PROGRAMSTATE(LastStmt, const void *)
+
 using namespace clang;
 using namespace ento;
 
@@ -986,7 +988,8 @@
   if (RS->getRetValue()) {
     for (ExplodedNodeSet::iterator it = dstPreVisit.begin(),
                                   ei = dstPreVisit.end(); it != ei; ++it) {
-      B.generateNode(RS, *it, (*it)->getState());
+      ProgramStateRef State = (*it)->getState();
+      B.generateNode(RS, *it, State->set<LastStmt>((const void*)RS));
     }
   }
 }


Index: test/Analysis/unreachable-code-path.c
===================================================================
--- test/Analysis/unreachable-code-path.c
+++ test/Analysis/unreachable-code-path.c
@@ -194,3 +194,14 @@
     break;
   }
 }
+
+extern int table[];
+static int inlineFunction(const int i) {
+  if (table[i] != 0) // <- SVal for table[0] is unknown
+    return 1;
+  return 0;
+}
+void test13(int i) {
+  int x = inlineFunction(i);
+  x && x < 10;
+}
Index: test/Analysis/inlining/InlineObjCClassMethod.m
===================================================================
--- test/Analysis/inlining/InlineObjCClassMethod.m
+++ test/Analysis/inlining/InlineObjCClassMethod.m
@@ -174,12 +174,12 @@
 @implementation MyClassSelf
 + (int)testClassMethodByKnownVarDecl {
   int y = [MyParentSelf testSelf];
-  return 5/y; // Should warn here.
+  return 5/y; // expected-warning{{Division by zero}}
 }
 @end
 int foo2() {
   int y = [MyParentSelf testSelf];
-  return 5/y; // Should warn here.
+  return 5/y; // expected-warning{{Division by zero}}
 }
 
 // TODO: We do not inline 'getNum' in the following case, where the value of 
Index: lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -23,6 +23,8 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/SaveAndRestore.h"
 
+REGISTER_TRAIT_WITH_PROGRAMSTATE(LastStmt, const void *)
+
 using namespace clang;
 using namespace ento;
 
@@ -986,7 +988,8 @@
   if (RS->getRetValue()) {
     for (ExplodedNodeSet::iterator it = dstPreVisit.begin(),
                                   ei = dstPreVisit.end(); it != ei; ++it) {
-      B.generateNode(RS, *it, (*it)->getState());
+      ProgramStateRef State = (*it)->getState();
+      B.generateNode(RS, *it, State->set<LastStmt>((const void*)RS));
     }
   }
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to