Index: lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp @@ -137,6 +137,10 @@ 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()) Index: lib/StaticAnalyzer/Core/BasicValueFactory.cpp =================================================================== --- lib/StaticAnalyzer/Core/BasicValueFactory.cpp +++ lib/StaticAnalyzer/Core/BasicValueFactory.cpp @@ -225,6 +225,8 @@ // 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; Index: test/Analysis/bitwise-ops.c =================================================================== --- test/Analysis/bitwise-ops.c +++ test/Analysis/bitwise-ops.c @@ -44,3 +44,10 @@ } 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; +}