/** * @name 04_MinIntNegate * @description Negating MIN_INT is an integer overflow * @kind problem * @id cpp/min-int-negate * @problem.severity warning */ import cpp import semmle.code.cpp.controlflow.Guards import semmle.code.cpp.valuenumbering.GlobalValueNumbering // Let's also add support for <= and >=. /** * Holds if `cond` is a comparison of the form `lhs < rhs`. * `isStrict` is true for < and >, and false for <= and >=. */ predicate lessThan(Expr cond, Expr lhs, Expr rhs, boolean isStrict) { cond.(LTExpr).getLeftOperand() = lhs and cond.(LTExpr).getRightOperand() = rhs and isStrict = true or cond.(GTExpr).getLeftOperand() = rhs and cond.(GTExpr).getRightOperand() = lhs and isStrict = true or cond.(LEExpr).getLeftOperand() = lhs and cond.(LEExpr).getRightOperand() = rhs and isStrict = false or cond.(GEExpr).getLeftOperand() = rhs and cond.(GEExpr).getRightOperand() = lhs and isStrict = false } from GuardCondition guard, BasicBlock block, UnaryMinusExpr unaryMinus, Expr use1, Expr use2, Expr zero where lessThan(guard, use1, zero, _) and zero.getValue().toInt() = 0 and guard.controls(block, true) and block.contains(unaryMinus) and unaryMinus.getOperand() = use2 and globalValueNumber(use1) = globalValueNumber(use2) select unaryMinus, "If the value of $@ is MinInt then this assignment will not make it positive", use2, use2.toString()