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