summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
diff options
context:
space:
mode:
authorGabor Horvath <xazax.hun@gmail.com>2018-01-22 13:32:10 +0000
committerGabor Horvath <xazax.hun@gmail.com>2018-01-22 13:32:10 +0000
commit596fcb1b0f609ed285e27fffc273d6b4e6a56890 (patch)
tree49c866ba1c9749a6da076ea66c47e3ac0a8d8dcc /clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
parente4d63a499d32d631041d6c1bcbd9f6e2309e690c (diff)
downloadbcm5719-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.cpp22
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())
OpenPOWER on IntegriCloud