diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll index 2dc735f49df..85a28fbc677 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll @@ -159,26 +159,56 @@ private predicate fieldAddressValueNumber( tvalueNumber(instr.getObjectAddress()) = objectAddress } +pragma[nomagic] +private predicate binaryValueNumber0( + BinaryInstruction instr, IRFunction irFunc, Opcode opcode, boolean isLeft, + TValueNumber valueNumber +) { + not instr instanceof PointerArithmeticInstruction and + instr.getEnclosingIRFunction() = irFunc and + instr.getOpcode() = opcode and + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate binaryValueNumber( BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand ) { - instr.getEnclosingIRFunction() = irFunc and - not instr instanceof PointerArithmeticInstruction and - instr.getOpcode() = opcode and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + binaryValueNumber0(instr, irFunc, opcode, true, leftOperand) and + binaryValueNumber0(instr, irFunc, opcode, false, rightOperand) } -private predicate pointerArithmeticValueNumber( +pragma[nomagic] +private predicate pointerArithmeticValueNumber0( PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, - TValueNumber leftOperand, TValueNumber rightOperand + boolean isLeft, TValueNumber valueNumber ) { instr.getEnclosingIRFunction() = irFunc and instr.getOpcode() = opcode and instr.getElementSize() = elementSize and - tvalueNumber(instr.getLeft()) = leftOperand and - tvalueNumber(instr.getRight()) = rightOperand + ( + isLeft = true and + tvalueNumber(instr.getLeft()) = valueNumber + or + isLeft = false and + tvalueNumber(instr.getRight()) = valueNumber + ) +} + +pragma[assume_small_delta] +private predicate pointerArithmeticValueNumber( + PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, + TValueNumber leftOperand, TValueNumber rightOperand +) { + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, true, leftOperand) and + pointerArithmeticValueNumber0(instr, irFunc, opcode, elementSize, false, rightOperand) } private predicate unaryValueNumber( @@ -203,14 +233,29 @@ private predicate inheritanceConversionValueNumber( unique( | | instr.getDerivedClass()) = derivedClass } +pragma[nomagic] +private predicate loadTotalOverlapValueNumber0( + LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber valueNumber, + boolean isAddress +) { + instr.getEnclosingIRFunction() = irFunc and + instr.getResultIRType() = type and + ( + isAddress = true and + tvalueNumberOfOperand(instr.getSourceAddressOperand()) = valueNumber + or + isAddress = false and + tvalueNumber(instr.getSourceValueOperand().getAnyDef()) = valueNumber + ) +} + +pragma[assume_small_delta] private predicate loadTotalOverlapValueNumber( LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber memOperand, TValueNumber operand ) { - instr.getEnclosingIRFunction() = irFunc and - tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and - tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and - instr.getResultIRType() = type + loadTotalOverlapValueNumber0(instr, irFunc, type, operand, true) and + loadTotalOverlapValueNumber0(instr, irFunc, type, memOperand, false) } /**