Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d9e6a6e

Browse files
author
Robert Marsh
committed
Move cached predicates to cached module
1 parent bf946c3 commit d9e6a6e

1 file changed

Lines changed: 76 additions & 73 deletions

File tree

cpp/ql/src/semmle/code/cpp/rangeanalysis/SignAnalysis.qll

Lines changed: 76 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import cpp
99
private import semmle.code.cpp.ir.IR
1010
private import semmle.code.cpp.controlflow.IRGuards
1111
private import semmle.code.cpp.ir.ValueNumbering
12+
private import SignAnalysisCached
1213

1314
private newtype TSign = TNeg() or TZero() or TPos()
1415
private class Sign extends TSign {
@@ -354,88 +355,90 @@ private predicate hasGuard(Instruction v, Instruction pos, Sign s) {
354355
s = TZero() and zeroBound(_, _, v, pos)
355356
}
356357

357-
/**
358-
* Gets a sign that `operand` may have at `pos`, taking guards into account.
359-
*/
360-
cached
361-
private Sign operandSign(Instruction pos, Instruction operand) {
362-
result = unguardedOperandSign(pos, operand)
363-
or
364-
result = guardedOperandSign(pos, operand) and
365-
result = guardedOperandSignOk(pos, operand)
366-
}
367-
368-
cached
369-
private Sign instructionSign(Instruction i) {
370-
result = certainInstructionSign(i)
371-
or
372-
not exists(certainInstructionSign(i)) and
373-
not (
374-
result = TNeg() and
375-
i.getResultType().(IntegralType).isUnsigned()
376-
) and
377-
(
378-
unknownSign(i)
379-
or
380-
exists(ConvertInstruction ci, Instruction prior, boolean fromSigned, boolean toSigned |
381-
i = ci and
382-
prior = ci.getOperand() and
383-
(
384-
if ci.getResultType().(IntegralType).isSigned()
385-
then toSigned = true
386-
else toSigned = false
387-
) and
388-
(
389-
if prior.getResultType().(IntegralType).isSigned()
390-
then fromSigned = true
391-
else fromSigned = false
392-
) and
393-
result = castSign(operandSign(ci, prior), fromSigned, toSigned, getCastKind(ci))
394-
)
395-
or
396-
exists(Instruction prior |
397-
prior = i.(CopyInstruction).getSourceValue()
398-
|
399-
result = operandSign(i, prior)
400-
)
401-
or
402-
result = operandSign(i, i.(BitComplementInstruction).getOperand()).bitnot()
358+
cached private module SignAnalysisCached {
359+
/**
360+
* Gets a sign that `operand` may have at `pos`, taking guards into account.
361+
*/
362+
cached
363+
Sign operandSign(Instruction pos, Instruction operand) {
364+
result = unguardedOperandSign(pos, operand)
403365
or
404-
result = operandSign(i, i.(NegateInstruction).getOperand()).neg()
366+
result = guardedOperandSign(pos, operand) and
367+
result = guardedOperandSignOk(pos, operand)
368+
}
369+
370+
cached
371+
Sign instructionSign(Instruction i) {
372+
result = certainInstructionSign(i)
405373
or
406-
exists(Sign s1, Sign s2 |
407-
binaryOpSigns(i, s1, s2)
408-
|
409-
i instanceof AddInstruction and result = s1.add(s2)
410-
or
411-
i instanceof SubInstruction and result = s1.add(s2.neg())
412-
or
413-
i instanceof MulInstruction and result = s1.mul(s2)
374+
not exists(certainInstructionSign(i)) and
375+
not (
376+
result = TNeg() and
377+
i.getResultType().(IntegralType).isUnsigned()
378+
) and
379+
(
380+
unknownSign(i)
414381
or
415-
i instanceof DivInstruction and result = s1.div(s2)
382+
exists(ConvertInstruction ci, Instruction prior, boolean fromSigned, boolean toSigned |
383+
i = ci and
384+
prior = ci.getOperand() and
385+
(
386+
if ci.getResultType().(IntegralType).isSigned()
387+
then toSigned = true
388+
else toSigned = false
389+
) and
390+
(
391+
if prior.getResultType().(IntegralType).isSigned()
392+
then fromSigned = true
393+
else fromSigned = false
394+
) and
395+
result = castSign(operandSign(ci, prior), fromSigned, toSigned, getCastKind(ci))
396+
)
416397
or
417-
i instanceof RemInstruction and result = s1.rem(s2)
398+
exists(Instruction prior |
399+
prior = i.(CopyInstruction).getSourceValue()
400+
|
401+
result = operandSign(i, prior)
402+
)
418403
or
419-
i instanceof BitAndInstruction and result = s1.bitand(s2)
404+
result = operandSign(i, i.(BitComplementInstruction).getOperand()).bitnot()
420405
or
421-
i instanceof BitOrInstruction and result = s1.bitor(s2)
406+
result = operandSign(i, i.(NegateInstruction).getOperand()).neg()
422407
or
423-
i instanceof BitXorInstruction and result = s1.bitxor(s2)
408+
exists(Sign s1, Sign s2 |
409+
binaryOpSigns(i, s1, s2)
410+
|
411+
i instanceof AddInstruction and result = s1.add(s2)
412+
or
413+
i instanceof SubInstruction and result = s1.add(s2.neg())
414+
or
415+
i instanceof MulInstruction and result = s1.mul(s2)
416+
or
417+
i instanceof DivInstruction and result = s1.div(s2)
418+
or
419+
i instanceof RemInstruction and result = s1.rem(s2)
420+
or
421+
i instanceof BitAndInstruction and result = s1.bitand(s2)
422+
or
423+
i instanceof BitOrInstruction and result = s1.bitor(s2)
424+
or
425+
i instanceof BitXorInstruction and result = s1.bitxor(s2)
426+
or
427+
i instanceof ShiftLeftInstruction and result = s1.lshift(s2)
428+
or
429+
i instanceof ShiftRightInstruction and
430+
i.getResultType().(IntegralType).isSigned() and
431+
result = s1.rshift(s2)
432+
or
433+
i instanceof ShiftRightInstruction and
434+
not i.getResultType().(IntegralType).isSigned() and
435+
result = s1.urshift(s2)
436+
)
424437
or
425-
i instanceof ShiftLeftInstruction and result = s1.lshift(s2)
426-
or
427-
i instanceof ShiftRightInstruction and
428-
i.getResultType().(IntegralType).isSigned() and
429-
result = s1.rshift(s2)
430-
or
431-
i instanceof ShiftRightInstruction and
432-
not i.getResultType().(IntegralType).isSigned() and
433-
result = s1.urshift(s2)
438+
// use hasGuard here?
439+
result = operandSign(i, i.(PhiInstruction).getAnOperand())
434440
)
435-
or
436-
// use hasGuard here?
437-
result = operandSign(i, i.(PhiInstruction).getAnOperand())
438-
)
441+
}
439442
}
440443

441444
/** Holds if `e` can be positive and cannot be negative. */

0 commit comments

Comments
 (0)