diff options
author | Gabor Horvath <xazax.hun@gmail.com> | 2017-10-30 17:06:42 +0000 |
---|---|---|
committer | Gabor Horvath <xazax.hun@gmail.com> | 2017-10-30 17:06:42 +0000 |
commit | 1416d5328a4350d5514ac8ec793acd461e6a38c5 (patch) | |
tree | 2f0f731dbe5d913075eabd4fd97bdaa1e4a695be /lib | |
parent | f822d3299b46ebefc293d06360e47a6bd731b4bd (diff) | |
download | clang-1416d5328a4350d5514ac8ec793acd461e6a38c5.tar.gz |
[analyzer] Left shifting a negative value is undefined
The analyzer did not return an UndefVal in case a negative value was left
shifted. I also altered the UndefResultChecker to emit a clear warning in this
case.
Differential Revision: https://reviews.llvm.org/D39423
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316924 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp | 4 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/BasicValueFactory.cpp | 2 |
2 files changed, 6 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp index 21e8b107c9..172ce346f1 100644 --- a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp @@ -137,6 +137,10 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B, OS << " greater or equal to the width of type '" << B->getLHS()->getType().getAsString() << "'."; + } else if (B->getOpcode() == BinaryOperatorKind::BO_Shl && + C.isNegative(B->getLHS())) { + OS << "The result of the left shift is undefined because the left " + "operand is negative"; } else { OS << "The result of the '" << BinaryOperator::getOpcodeStr(B->getOpcode()) diff --git a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp index ebbace4e33..ec7a7e9e4b 100644 --- a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp +++ b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp @@ -225,6 +225,8 @@ BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op, // test these conditions symbolically. // FIXME: Expand these checks to include all undefined behavior. + if (V1.isSigned() && V1.isNegative()) + return nullptr; if (V2.isSigned() && V2.isNegative()) return nullptr; |