diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-01-04 08:18:09 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-01-04 08:18:09 +0000 |
commit | d1247c5002ee511e6f6c3c26214221c391d437cd (patch) | |
tree | 293e53956a80285e21dcb66d0204e2901854761d /lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | |
parent | d6aba06861c41ccbc4926e5fe3cecd97b20410c0 (diff) |
Extend ConditionBRVisitor to handle condition variable assignments.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147526 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/BugReporterVisitors.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 6828a9e159..88f38a3e4b 100644 --- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -604,18 +604,26 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond, shouldInvert = !isVarLHS && isVarRHS; } + BinaryOperator::Opcode Op = BExpr->getOpcode(); + + if (BinaryOperator::isAssignmentOp(Op)) { + // For assignment operators, all that we care about is that the LHS + // evaluates to "true" or "false". + return VisitConditionVariable(LhsString, BExpr->getLHS(), tookTrue, + BRC, LC); + } + + // For non-assignment operations, we require that we can understand + // both the LHS and RHS. if (LhsString.empty() || RhsString.empty()) return 0; - - // Should we invert the strings if the LHS is not a variable name? + // Should we invert the strings if the LHS is not a variable name? llvm::SmallString<256> buf; llvm::raw_svector_ostream Out(buf); Out << "Assuming " << (shouldInvert ? RhsString : LhsString) << " is "; // Do we need to invert the opcode? - BinaryOperator::Opcode Op = BExpr->getOpcode(); - if (shouldInvert) switch (Op) { default: break; @@ -654,6 +662,33 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond, PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LC); return new PathDiagnosticEventPiece(Loc, Out.str()); } + +PathDiagnosticPiece * +ConditionBRVisitor::VisitConditionVariable(StringRef LhsString, + const Expr *CondVarExpr, + const bool tookTrue, + BugReporterContext &BRC, + const LocationContext *LC) { + llvm::SmallString<256> buf; + llvm::raw_svector_ostream Out(buf); + Out << "Assuming " << LhsString << " is "; + + QualType Ty = CondVarExpr->getType(); + + if (Ty->isPointerType()) + Out << (tookTrue ? "not null" : "null"); + else if (Ty->isObjCObjectPointerType()) + Out << (tookTrue ? "not nil" : "nil"); + else if (Ty->isBooleanType()) + Out << (tookTrue ? "true" : "false"); + else if (Ty->isIntegerType()) + Out << (tookTrue ? "non-zero" : "zero"); + else + return 0; + + PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LC); + return new PathDiagnosticEventPiece(Loc, Out.str()); +} PathDiagnosticPiece * ConditionBRVisitor::VisitTrueTest(const Expr *Cond, |