summaryrefslogtreecommitdiffstats
path: root/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2017-04-24 20:55:07 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2017-04-24 20:55:07 +0000
commit51381410d47fcdf3debc3505512ede786cd70bc4 (patch)
tree33f47e57a114f9461a23ccb698910a77874aeec5 /lib/StaticAnalyzer
parent1e969193c25a8b22e8aa078baf2a00feb7f722d5 (diff)
[analyzer] Improve subscripting null arrays for catching null dereferences.
Array-to-pointer cast now works correctly when the pointer to the array is concrete, eg. null, which allows further symbolic calculations involving such values. Inlined defensive checks are now detected correctly when the resulting null symbol is being array-subscripted before dereference. Differential Revision: https://reviews.llvm.org/D32291 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@301251 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer')
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp19
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp3
2 files changed, 12 insertions, 10 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index ec9fd6c75e..d00182a871 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -61,7 +61,9 @@ const Expr *bugreporter::getDerefExpr(const Stmt *S) {
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 @@ const Expr *bugreporter::getDerefExpr(const Stmt *S) {
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 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
// 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;
}
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index dd7e9dd117..3000e13d32 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -1338,6 +1338,9 @@ RegionStoreManager::getSizeInElements(ProgramStateRef state,
/// 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();