diff options
| author | Gabor Horvath <xazax.hun@gmail.com> | 2018-01-22 13:32:10 +0000 |
|---|---|---|
| committer | Gabor Horvath <xazax.hun@gmail.com> | 2018-01-22 13:32:10 +0000 |
| commit | 596fcb1b0f609ed285e27fffc273d6b4e6a56890 (patch) | |
| tree | 49c866ba1c9749a6da076ea66c47e3ac0a8d8dcc /clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp | |
| parent | e4d63a499d32d631041d6c1bcbd9f6e2309e690c (diff) | |
| download | bcm5719-llvm-596fcb1b0f609ed285e27fffc273d6b4e6a56890.tar.gz bcm5719-llvm-596fcb1b0f609ed285e27fffc273d6b4e6a56890.zip | |
[analyzer] Model and check unrepresentable left shifts
Patch by: Reka Nikolett Kovacs
Differential Revision: https://reviews.llvm.org/D41816
llvm-svn: 323115
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp index 08e9a08bfc9..b9a93bedca2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp @@ -63,6 +63,15 @@ static bool isShiftOverflow(const BinaryOperator *B, CheckerContext &C) { B->getRHS(), C.getASTContext().getIntWidth(B->getLHS()->getType())); } +static bool isLeftShiftResultUnrepresentable(const BinaryOperator *B, + CheckerContext &C) { + SValBuilder &SB = C.getSValBuilder(); + ProgramStateRef State = C.getState(); + const llvm::APSInt *LHS = SB.getKnownValue(State, C.getSVal(B->getLHS())); + const llvm::APSInt *RHS = SB.getKnownValue(State, C.getSVal(B->getRHS())); + return (unsigned)RHS->getZExtValue() > LHS->countLeadingZeros(); +} + void UndefResultChecker::checkPostStmt(const BinaryOperator *B, CheckerContext &C) const { if (C.getSVal(B).isUndef()) { @@ -138,6 +147,19 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B, C.isNegative(B->getLHS())) { OS << "The result of the left shift is undefined because the left " "operand is negative"; + } else if (B->getOpcode() == BinaryOperatorKind::BO_Shl && + isLeftShiftResultUnrepresentable(B, C)) { + ProgramStateRef State = C.getState(); + SValBuilder &SB = C.getSValBuilder(); + const llvm::APSInt *LHS = + SB.getKnownValue(State, C.getSVal(B->getLHS())); + const llvm::APSInt *RHS = + SB.getKnownValue(State, C.getSVal(B->getRHS())); + OS << "The result of the left shift is undefined due to shifting \'" + << LHS->getSExtValue() << "\' by \'" << RHS->getZExtValue() + << "\', which is unrepresentable in the unsigned version of " + << "the return type \'" << B->getLHS()->getType().getAsString() + << "\'"; } else { OS << "The result of the '" << BinaryOperator::getOpcodeStr(B->getOpcode()) |

