Skip to content

Commit

Permalink
[analyzer] Left shifting a negative value is undefined
Browse files Browse the repository at this point in the history
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

llvm-svn: 316924
  • Loading branch information
Xazax-hun committed Oct 30, 2017
1 parent 0f4c571 commit 4581f74
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 0 deletions.
4 changes: 4 additions & 0 deletions clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
Expand Up @@ -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())
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
Expand Up @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions clang/test/Analysis/bitwise-ops.c
Expand Up @@ -44,3 +44,10 @@ int testNegativeShift(int a) {
}
return 0;
}

int testNegativeLeftShift(int a) {
if (a == -3) {
return a << 1; // expected-warning{{The result of the left shift is undefined because the left operand is negative}}
}
return 0;
}

0 comments on commit 4581f74

Please sign in to comment.