summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
index 137dedbf4ce..89b1358a2a5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
@@ -862,6 +862,30 @@ void NullabilityChecker::checkPostStmt(const ExplicitCastExpr *CE,
}
}
+/// For a given statement performing a bind, attempt to syntactically
+/// match the expression resulting in the bound value.
+static const Expr * matchValueExprForBind(const Stmt *S) {
+ // For `x = e` the value expression is the right-hand side.
+ if (auto *BinOp = dyn_cast<BinaryOperator>(S)) {
+ if (BinOp->getOpcode() == BO_Assign)
+ return BinOp->getRHS();
+ }
+
+ // For `int x = e` the value expression is the initializer.
+ if (auto *DS = dyn_cast<DeclStmt>(S)) {
+ if (DS->isSingleDecl()) {
+ auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
+ if (!VD)
+ return nullptr;
+
+ if (const Expr *Init = VD->getInit())
+ return Init;
+ }
+ }
+
+ return nullptr;
+}
+
/// Propagate the nullability information through binds and warn when nullable
/// pointer or null symbol is assigned to a pointer with a nonnull type.
void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S,
@@ -898,8 +922,13 @@ void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S,
ExplodedNode *N = C.generateErrorNode(State, &Tag);
if (!N)
return;
+
+ const Stmt *ValueExpr = matchValueExprForBind(S);
+ if (!ValueExpr)
+ ValueExpr = S;
+
reportBugIfPreconditionHolds(ErrorKind::NilAssignedToNonnull, N, nullptr, C,
- S);
+ ValueExpr);
return;
}
// Intentionally missing case: '0' is bound to a reference. It is handled by
OpenPOWER on IntegriCloud