Lines Matching +full:side +full:- +full:by +full:- +full:side
1 //== BitwiseShiftChecker.cpp ------------------------------------*- C++ -*--==//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file defines BitwiseShiftChecker, which is a path-sensitive checker
13 //===----------------------------------------------------------------------===//
45 {"left operand of bit shift is non-negative", " and right operand is less than "},
46 {"right operand of bit shift is non-negative", " but less than "},
47 {"both operands of bit shift are non-negative", " and right operand is less than "}
73 const Expr *operandExpr(OperandSide Side) const { in operandExpr()
74 return Side == OperandSide::Left ? Op->getLHS() : Op->getRHS(); in operandExpr()
83 bool assumeRequirement(OperandSide Side, BinaryOperator::Opcode Cmp, unsigned Limit);
85 void recordAssumption(OperandSide Side, BinaryOperator::Opcode Cmp, unsigned Limit);
91 BugReportPtr checkOperandNegative(OperandSide Side);
94 bool isLeftShift() const { return Op->getOpcode() == BO_Shl; } in isLeftShift()
133 /// This method checks a requirement that must be satisfied by the value on the
134 /// given Side of a bitwise shift operator in well-defined code. If the
136 /// failure by returning false.
137 bool BitwiseShiftValidator::assumeRequirement(OperandSide Side, in assumeRequirement() argument
142 const SVal OperandVal = Ctx.getSVal(operandExpr(Side)); in assumeRequirement()
150 auto [StTrue, StFalse] = FoldedState->assume(DURes.value()); in assumeRequirement()
160 recordAssumption(Side, Comparison, Limit); in assumeRequirement()
167 const QualType LHSTy = Op->getLHS()->getType(); in checkOvershift()
177 RightOpStr = formatv(" '{0}'", ConcreteRight->getValue()); in checkOvershift()
181 LowerBoundStr = formatv(" >= {0},", MinRight->getExtValue()); in checkOvershift()
187 isLeftShift() ? "Left" : "Right", RightOpStr.empty() ? "" : " by", in checkOvershift()
196 // Before C++20, at 5.8 [expr.shift] (N4296, 2014-11-19) the standard says
199 // if E1 has a signed type and non-negative value ...
203 // the resulting value is implementation-defined."
206 BugReportPtr BitwiseShiftValidator::checkOperandNegative(OperandSide Side) { in checkOperandNegative() argument
208 if (!operandExpr(Side)->getType()->isSignedIntegerType()) in checkOperandNegative()
212 if (assumeRequirement(Side, BO_GE, 0)) in checkOperandNegative()
216 Side == OperandSide::Left ? "Left" : "Right", in checkOperandNegative()
222 Side == OperandSide::Left ? "left" : "right") in checkOperandNegative()
233 // In C++ it's well-defined to shift to the sign bit. In C however, it's UB. in checkLeftShiftOverflow()
234 // 5.8.2 [expr.shift] (N4296, 2014-11-19) in checkLeftShiftOverflow()
238 const QualType LHSTy = LHS->getType(); in checkLeftShiftOverflow()
244 if (LHSTy->isUnsignedIntegerType()) in checkLeftShiftOverflow()
254 assert(Left->getValue().isNonNegative()); in checkLeftShiftOverflow()
257 LeftBitWidth - static_cast<unsigned>(ShouldPreserveSignBit); in checkLeftShiftOverflow()
258 const unsigned UsedBitsInLeftOperand = Left->getValue().getActiveBits(); in checkLeftShiftOverflow()
261 LeftAvailableBitWidth - UsedBitsInLeftOperand; in checkLeftShiftOverflow()
271 const SVal Right = Ctx.getSVal(Op->getRHS()); in checkLeftShiftOverflow()
275 // Here ConcreteRight must contain a small non-negative integer, because in checkLeftShiftOverflow()
277 const unsigned RHS = ConcreteRight->getValue().getExtValue(); in checkLeftShiftOverflow()
279 const unsigned OverflownBits = RHS - MaximalAllowedShift; in checkLeftShiftOverflow()
282 Left->getValue(), ConcreteRight->getValue(), LHSTy.getAsString()); in checkLeftShiftOverflow()
285 Left->getValue(), ConcreteRight->getValue(), CapacityMsg, OverflownBits, in checkLeftShiftOverflow()
289 Left->getValue(), LHSTy.getAsString()); in checkLeftShiftOverflow()
292 Left->getValue(), CapacityMsg); in checkLeftShiftOverflow()
298 void BitwiseShiftValidator::recordAssumption(OperandSide Side, in recordAssumption() argument
304 NonNegOperands |= (Side == OperandSide::Left ? NonNegLeft : NonNegRight); in recordAssumption()
307 assert(Side == OperandSide::Right); in recordAssumption()
338 bugreporter::trackExpressionValue(ErrNode, Op->getLHS(), *BR); in createBugReport()
339 bugreporter::trackExpressionValue(ErrNode, Op->getRHS(), *BR); in createBugReport()
351 BinaryOperator::Opcode Op = B->getOpcode(); in checkPreStmt()
365 Chk->Pedantic = Opts.getCheckerBooleanOption(Chk, "Pedantic"); in registerBitwiseShiftChecker()