This revision was automatically updated to reflect the committed changes. Closed by commit rGa88025672f89: [analyzer] Consider array subscripts to be interesting lvalues. (authored by vsavchenko, committed by dergachev.a).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78638/new/ https://reviews.llvm.org/D78638 Files: clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp clang/test/Analysis/CheckThatArraySubsciptNodeIsNotCollected.cpp Index: clang/test/Analysis/CheckThatArraySubsciptNodeIsNotCollected.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/CheckThatArraySubsciptNodeIsNotCollected.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s + +class A { +public: + int method(); +}; + +A *foo(); +void bar(A *); + +int index; + +// We want to check here that the notes about the origins of the null pointer +// (array[index] = foo()) will get to the final report. +// +// The analyzer used to drop exploded nodes for array subscripts when it was +// time to collect redundant nodes. This GC-like mechanism kicks in only when +// the exploded graph is large enough (>1K nodes). For this reason, 'index' +// is a global variable, and the sink point is inside of a loop. + +void test() { + A *array[42]; + A *found; + + for (index = 0; (array[index] = foo()); ++index) { // expected-note {{Loop condition is false. Execution continues on line 34}} + // expected-note@-1 {{Value assigned to 'index'}} + // expected-note@-2 {{Assigning value}} + // expected-note@-3 {{Assuming pointer value is null}} + if (array[0]) + break; + } + + do { + found = array[index]; // expected-note {{Null pointer value stored to 'found'}} + + if (found->method()) // expected-warning {{Called C++ object pointer is null [core.CallAndMessage]}} + // expected-note@-1 {{Called C++ object pointer is null}} + bar(found); + } while (--index); +} Index: clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -50,9 +50,8 @@ bool ExplodedGraph::isInterestingLValueExpr(const Expr *Ex) { if (!Ex->isLValue()) return false; - return isa<DeclRefExpr>(Ex) || - isa<MemberExpr>(Ex) || - isa<ObjCIvarRefExpr>(Ex); + return isa<DeclRefExpr>(Ex) || isa<MemberExpr>(Ex) || + isa<ObjCIvarRefExpr>(Ex) || isa<ArraySubscriptExpr>(Ex); } bool ExplodedGraph::shouldCollect(const ExplodedNode *node) {
Index: clang/test/Analysis/CheckThatArraySubsciptNodeIsNotCollected.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/CheckThatArraySubsciptNodeIsNotCollected.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s + +class A { +public: + int method(); +}; + +A *foo(); +void bar(A *); + +int index; + +// We want to check here that the notes about the origins of the null pointer +// (array[index] = foo()) will get to the final report. +// +// The analyzer used to drop exploded nodes for array subscripts when it was +// time to collect redundant nodes. This GC-like mechanism kicks in only when +// the exploded graph is large enough (>1K nodes). For this reason, 'index' +// is a global variable, and the sink point is inside of a loop. + +void test() { + A *array[42]; + A *found; + + for (index = 0; (array[index] = foo()); ++index) { // expected-note {{Loop condition is false. Execution continues on line 34}} + // expected-note@-1 {{Value assigned to 'index'}} + // expected-note@-2 {{Assigning value}} + // expected-note@-3 {{Assuming pointer value is null}} + if (array[0]) + break; + } + + do { + found = array[index]; // expected-note {{Null pointer value stored to 'found'}} + + if (found->method()) // expected-warning {{Called C++ object pointer is null [core.CallAndMessage]}} + // expected-note@-1 {{Called C++ object pointer is null}} + bar(found); + } while (--index); +} Index: clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -50,9 +50,8 @@ bool ExplodedGraph::isInterestingLValueExpr(const Expr *Ex) { if (!Ex->isLValue()) return false; - return isa<DeclRefExpr>(Ex) || - isa<MemberExpr>(Ex) || - isa<ObjCIvarRefExpr>(Ex); + return isa<DeclRefExpr>(Ex) || isa<MemberExpr>(Ex) || + isa<ObjCIvarRefExpr>(Ex) || isa<ArraySubscriptExpr>(Ex); } bool ExplodedGraph::shouldCollect(const ExplodedNode *node) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits