/** * @name 03_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 // The previous query only worked for `x < 0` and not for the // equivalent `0 > x`. It's easier to handle both if we refactor // the logic into a separate predicate. /** Holds if `cond` is a comparison of the form `lhs < rhs`. */ predicate lessThan(Expr cond, Expr lhs, Expr rhs) { cond.(LTExpr).getLeftOperand() = lhs and cond.(LTExpr).getRightOperand() = rhs or cond.(GTExpr).getLeftOperand() = rhs and cond.(GTExpr).getRightOperand() = lhs } 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()