[PATCH] D32291: [analyzer] Implement handling array subscript into null pointer, improve null dereference checks for array subscripts
Phabricator via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 24 14:08:15 PDT 2017
This revision was automatically updated to reflect the committed changes.
Closed by commit rL301251: [analyzer] Improve subscripting null arrays for catching null dereferences. (authored by dergachev).
Changed prior to commit:
https://reviews.llvm.org/D32291?vs=95943&id=96468#toc
Repository:
rL LLVM
https://reviews.llvm.org/D32291
Files:
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
cfe/trunk/test/Analysis/null-deref-offsets.c
Index: cfe/trunk/test/Analysis/null-deref-offsets.c
===================================================================
--- cfe/trunk/test/Analysis/null-deref-offsets.c
+++ cfe/trunk/test/Analysis/null-deref-offsets.c
@@ -7,7 +7,7 @@
int z[2];
};
-void testOffsets(struct S *s) {
+void testOffsets(struct S *s, int coin) {
if (s != 0)
return;
@@ -21,14 +21,17 @@
// FIXME: These should ideally be true.
clang_analyzer_eval(&(s->y) == 4); // expected-warning{{FALSE}}
- clang_analyzer_eval(&(s->z[0]) == 8); // expected-warning{{UNKNOWN}}
- clang_analyzer_eval(&(s->z[1]) == 12); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(&(s->z[0]) == 8); // expected-warning{{FALSE}}
+ clang_analyzer_eval(&(s->z[1]) == 12); // expected-warning{{FALSE}}
// FIXME: These should ideally be false.
clang_analyzer_eval(&(s->y) == 0); // expected-warning{{TRUE}}
- clang_analyzer_eval(&(s->z[0]) == 0); // expected-warning{{UNKNOWN}}
- clang_analyzer_eval(&(s->z[1]) == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(&(s->z[0]) == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(&(s->z[1]) == 0); // expected-warning{{TRUE}}
- // But this should still be a null dereference.
- s->y = 5; // expected-warning{{Access to field 'y' results in a dereference of a null pointer (loaded from variable 's')}}
+ // But these should still be reported as null dereferences.
+ if (coin)
+ s->y = 5; // expected-warning{{Access to field 'y' results in a dereference of a null pointer (loaded from variable 's')}}
+ else
+ s->z[1] = 6; // expected-warning{{Array access (via field 'z') results in a null pointer dereference}}
}
Index: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -61,7 +61,9 @@
return U->getSubExpr()->IgnoreParenCasts();
}
else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
- if (ME->isArrow() || isDeclRefExprToReference(ME->getBase())) {
+ if (ME->isImplicitAccess()) {
+ return ME;
+ } else if (ME->isArrow() || isDeclRefExprToReference(ME->getBase())) {
return ME->getBase()->IgnoreParenCasts();
} else {
// If we have a member expr with a dot, the base must have been
@@ -73,9 +75,9 @@
return IvarRef->getBase()->IgnoreParenCasts();
}
else if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(E)) {
- return AE->getBase();
+ return getDerefExpr(AE->getBase());
}
- else if (isDeclRefExprToReference(E)) {
+ else if (isa<DeclRefExpr>(E)) {
return E;
}
break;
@@ -974,14 +976,11 @@
// This code interacts heavily with this hack; otherwise the value
// would not be null at all for most fields, so we'd be unable to track it.
if (const auto *Op = dyn_cast<UnaryOperator>(Ex))
- if (Op->getOpcode() == UO_AddrOf && Op->getSubExpr()->isLValue()) {
- Ex = Op->getSubExpr()->IgnoreParenCasts();
- while (const auto *ME = dyn_cast<MemberExpr>(Ex)) {
- Ex = ME->getBase()->IgnoreParenCasts();
- }
- }
+ if (Op->getOpcode() == UO_AddrOf && Op->getSubExpr()->isLValue())
+ if (const Expr *DerefEx = getDerefExpr(Op->getSubExpr()))
+ Ex = DerefEx;
- if (ExplodedGraph::isInterestingLValueExpr(Ex) || CallEvent::isCallStmt(Ex))
+ if (Ex && (ExplodedGraph::isInterestingLValueExpr(Ex) || CallEvent::isCallStmt(Ex)))
Inner = Ex;
}
Index: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -1338,6 +1338,9 @@
/// the array). This is called by ExprEngine when evaluating casts
/// from arrays to pointers.
SVal RegionStoreManager::ArrayToPointer(Loc Array, QualType T) {
+ if (Array.getAs<loc::ConcreteInt>())
+ return Array;
+
if (!Array.getAs<loc::MemRegionVal>())
return UnknownVal();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32291.96468.patch
Type: text/x-patch
Size: 4181 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170424/dc9e79e3/attachment-0001.bin>
More information about the cfe-commits
mailing list