mirror of
https://github.com/github/codeql.git
synced 2026-05-05 05:35:13 +02:00
Add ConstantLShiftExprRange and ConstantRShiftExprRange classes
This commit is contained in:
committed by
Gulshan Singh
parent
5710289460
commit
051d36ee6a
@@ -0,0 +1,152 @@
|
||||
private import cpp
|
||||
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
|
||||
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
||||
|
||||
float evaluateConstantExpr2(Expr e) {
|
||||
result = e.getValue().toFloat()
|
||||
or
|
||||
// This handles when a constant value is put into a variable
|
||||
// and the variable is used later
|
||||
exists(SsaDefinition defn, StackVariable sv |
|
||||
defn.getAUse(sv) = e and
|
||||
result = defn.getDefiningValue(sv).getValue().toFloat()
|
||||
)
|
||||
}
|
||||
|
||||
// If the constant right operand is negative or is greater than or equal to the number of
|
||||
// bits in the left operands type, then the result is undefined (except on the IA-32
|
||||
// architecture where the shift value is masked with 0b00011111, but we can't
|
||||
// assume the architecture).
|
||||
bindingset[val]
|
||||
pragma[inline]
|
||||
private predicate isValidShiftExprShift(float val, Expr l) {
|
||||
val >= 0 and
|
||||
// We use getFullyConverted because the spec says to use the *promoted* left operand
|
||||
val < (l.getFullyConverted().getUnderlyingType().getSize() * 8)
|
||||
}
|
||||
|
||||
bindingset[val, shift, max_val]
|
||||
private predicate canLShiftOverflow(int val, int shift, int max_val) {
|
||||
// val << shift = val * 2^shift > max_val => val > max_val/2^shift = max_val >> b
|
||||
val > max_val.bitShiftRight(shift)
|
||||
}
|
||||
|
||||
/**
|
||||
* This handles the `<<` and `<<=` operators when at least one operand is a constant (and if the right operand
|
||||
* is a constant, it must be "valid" (see `isValidShiftExprShift`)). When handling any undefined behavior, it
|
||||
* leaves the values unconstrained. From the C++ standard: "The behavior is undefined if the right
|
||||
* operand is negative, or greater than or equal to the length in bits of the promoted left operand.
|
||||
* The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1
|
||||
* has an unsigned type, the value of the result is E1 × 2 E2, reduced modulo one more than the
|
||||
* maximum value representable in the result type. Otherwise, if E1 has a signed type and
|
||||
* non-negative value, and E1 × 2 E2 is representable in the corresponding unsigned type of the
|
||||
* result type, then that value, converted to the result type, is the resulting value; otherwise,
|
||||
* the behavior is undefined."
|
||||
*/
|
||||
class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
|
||||
/**
|
||||
* Holds for `a << b` or `a <<= b` in one of the following two cases:
|
||||
* 1. `a` is a constant and `b` is not
|
||||
* 2. `b` is constant
|
||||
*
|
||||
* We don't handle the case where `a` and `b` are both non-constant values.
|
||||
*/
|
||||
ConstantLShiftExprRange() {
|
||||
getUnspecifiedType() instanceof IntegralType and
|
||||
exists(Expr l, Expr r |
|
||||
l = this.(LShiftExpr).getLeftOperand() and
|
||||
r = this.(LShiftExpr).getRightOperand()
|
||||
or
|
||||
l = this.(AssignLShiftExpr).getLValue() and
|
||||
r = this.(AssignLShiftExpr).getRValue()
|
||||
|
|
||||
l.getUnspecifiedType() instanceof IntegralType and
|
||||
r.getUnspecifiedType() instanceof IntegralType and
|
||||
(
|
||||
// If the left operand is a constant, verify that the right operand is not a constant
|
||||
exists(evaluateConstantExpr2(l)) and not exists(evaluateConstantExpr2(r))
|
||||
or
|
||||
// If the right operand is a constant, check if it is a valid shift expression
|
||||
exists(float constROp |
|
||||
constROp = evaluateConstantExpr2(r) and isValidShiftExprShift(constROp, l)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Expr getLeftOperand() {
|
||||
result = this.(LShiftExpr).getLeftOperand() or
|
||||
result = this.(AssignLShiftExpr).getLValue()
|
||||
}
|
||||
|
||||
Expr getRightOperand() {
|
||||
result = this.(LShiftExpr).getRightOperand() or
|
||||
result = this.(AssignLShiftExpr).getRValue()
|
||||
}
|
||||
|
||||
override float getLowerBounds() {
|
||||
exists(int lLower, int lUpper, int rLower, int rUpper |
|
||||
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
|
||||
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
|
||||
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
|
||||
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
|
||||
lLower <= lUpper and
|
||||
rLower <= rUpper
|
||||
|
|
||||
if
|
||||
lLower < 0
|
||||
or
|
||||
not (
|
||||
isValidShiftExprShift(rLower, getLeftOperand()) and
|
||||
isValidShiftExprShift(rUpper, getLeftOperand())
|
||||
)
|
||||
then
|
||||
// We don't want to deal with shifting negative numbers at the moment,
|
||||
// and a negative shift is undefined, so we set to the minimum value
|
||||
result = exprMinVal(this)
|
||||
else
|
||||
// If we have `0b01010000 << [0, 2]`, the max value for 8 bits is 0b10100000
|
||||
// (a shift of 1) but doing a shift by the upper bound would give 0b01000000.
|
||||
// So if the left shift operation causes an overflow, we just assume the max value
|
||||
// If necessary, we may be able to improve this bound in the future
|
||||
if canLShiftOverflow(lUpper, rUpper, exprMaxVal(this).(int))
|
||||
then result = exprMinVal(this)
|
||||
else result = lLower.bitShiftLeft(rLower)
|
||||
)
|
||||
}
|
||||
|
||||
override float getUpperBounds() {
|
||||
exists(int lLower, int lUpper, int rLower, int rUpper |
|
||||
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
|
||||
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
|
||||
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
|
||||
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
|
||||
lLower <= lUpper and
|
||||
rLower <= rUpper
|
||||
|
|
||||
if
|
||||
lLower < 0
|
||||
or
|
||||
not (
|
||||
isValidShiftExprShift(rLower, getLeftOperand()) and
|
||||
isValidShiftExprShift(rUpper, getLeftOperand())
|
||||
)
|
||||
then
|
||||
// We don't want to deal with shifting negative numbers at the moment,
|
||||
// and a negative shift is undefined, so we set it to the maximum value
|
||||
result = exprMaxVal(this)
|
||||
else
|
||||
// If we have `0b01010000 << [0, 2]`, the max value for 8 bits is 0b10100000
|
||||
// (a shift of 1) but doing a shift by the upper bound would give 0b01000000.
|
||||
// So if the left shift operation causes an overflow, we just assume the max value
|
||||
// If necessary, we may be able to improve this bound in the future
|
||||
if canLShiftOverflow(lUpper, rUpper, exprMaxVal(this).(int))
|
||||
then result = exprMaxVal(this)
|
||||
else result = lUpper.bitShiftLeft(rUpper)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate dependsOnChild(Expr child) {
|
||||
child = getLeftOperand() or child = getLeftOperand()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
private import cpp
|
||||
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
|
||||
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
||||
|
||||
float evaluateConstantExpr1(Expr e) {
|
||||
result = e.getValue().toFloat()
|
||||
or
|
||||
// This handles when a constant value is put into a variable
|
||||
// and the variable is used later
|
||||
exists(SsaDefinition defn, StackVariable sv |
|
||||
defn.getAUse(sv) = e and
|
||||
result = defn.getDefiningValue(sv).getValue().toFloat()
|
||||
)
|
||||
}
|
||||
|
||||
// If the constant right operand is negative or is greater than or equal to the number of
|
||||
// bits in the left operands type, then the result is undefined (except on the IA-32
|
||||
// architecture where the shift value is masked with 0b00011111, but we can't
|
||||
// assume the architecture).
|
||||
bindingset[val]
|
||||
pragma[inline]
|
||||
private predicate isValidShiftExprShift(float val, Expr l) {
|
||||
val >= 0 and
|
||||
// We use getFullyConverted because the spec says to use the *promoted* left operand
|
||||
val < (l.getFullyConverted().getUnderlyingType().getSize() * 8)
|
||||
}
|
||||
|
||||
/**
|
||||
* This handles the `>>` and `>>=` operators when at least one operand is a constant (and if the
|
||||
* right operand is a constant, it must be "valid" (see `isValidShiftExprShift`)). When handling any
|
||||
* undefined behavior, it leaves the values unconstrained. From the C++ standard: "The behavior is
|
||||
* undefined if the right operand is negative, or greater than or equal to the length in bits of the
|
||||
* promoted left operand. The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an
|
||||
* unsigned type or if E1 has a signed type and a non-negative value, the value of the result is the
|
||||
* integral part of the quotient of E1/2^E2. If E1 has a signed type and a negative value, the
|
||||
* resulting value is implementation-defined."
|
||||
*/
|
||||
class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
|
||||
/**
|
||||
* Holds for `a >> b` or `a >>= b` in one of the following two cases:
|
||||
* 1. `a` is a constant and `b` is not
|
||||
* 2. `b` is constant
|
||||
*
|
||||
* We don't handle the case where `a` and `b` are both non-constant values.
|
||||
*/
|
||||
ConstantRShiftExprRange() {
|
||||
getUnspecifiedType() instanceof IntegralType and
|
||||
exists(Expr l, Expr r |
|
||||
l = this.(RShiftExpr).getLeftOperand() and
|
||||
r = this.(RShiftExpr).getRightOperand()
|
||||
or
|
||||
l = this.(AssignRShiftExpr).getLValue() and
|
||||
r = this.(AssignRShiftExpr).getRValue()
|
||||
|
|
||||
l.getUnspecifiedType() instanceof IntegralType and
|
||||
r.getUnspecifiedType() instanceof IntegralType and
|
||||
(
|
||||
// If the left operand is a constant, verify that the right operand is not a constant
|
||||
exists(evaluateConstantExpr1(l)) and not exists(evaluateConstantExpr1(r))
|
||||
or
|
||||
// If the right operand is a constant, check if it is a valid shift expression
|
||||
exists(float constROp |
|
||||
constROp = evaluateConstantExpr1(r) and isValidShiftExprShift(constROp, l)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Expr getLeftOperand() {
|
||||
result = this.(RShiftExpr).getLeftOperand() or
|
||||
result = this.(AssignRShiftExpr).getLValue()
|
||||
}
|
||||
|
||||
Expr getRightOperand() {
|
||||
result = this.(RShiftExpr).getRightOperand() or
|
||||
result = this.(AssignRShiftExpr).getRValue()
|
||||
}
|
||||
|
||||
override float getLowerBounds() {
|
||||
exists(int lLower, int lUpper, int rLower, int rUpper |
|
||||
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
|
||||
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
|
||||
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
|
||||
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
|
||||
lLower <= lUpper and
|
||||
rLower <= rUpper
|
||||
|
|
||||
if
|
||||
lLower < 0
|
||||
or
|
||||
not (
|
||||
isValidShiftExprShift(rLower, getLeftOperand()) and
|
||||
isValidShiftExprShift(rUpper, getLeftOperand())
|
||||
)
|
||||
then
|
||||
// We don't want to deal with shifting negative numbers at the moment,
|
||||
// and a negative shift is implementation defined, so we set the result
|
||||
// to the minimum value
|
||||
result = exprMinVal(this)
|
||||
else
|
||||
// We can get the smallest value by shifting the smallest bound by the largest bound
|
||||
result = lLower.bitShiftRight(rUpper)
|
||||
)
|
||||
}
|
||||
|
||||
override float getUpperBounds() {
|
||||
exists(int lLower, int lUpper, int rLower, int rUpper |
|
||||
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
|
||||
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
|
||||
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
|
||||
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
|
||||
lLower <= lUpper and
|
||||
rLower <= rUpper
|
||||
|
|
||||
if
|
||||
lLower < 0
|
||||
or
|
||||
not (
|
||||
isValidShiftExprShift(rLower, getLeftOperand()) and
|
||||
isValidShiftExprShift(rUpper, getLeftOperand())
|
||||
)
|
||||
then
|
||||
// We don't want to deal with shifting negative numbers at the moment,
|
||||
// and a negative shift is implementation defined, so we set the result
|
||||
// to the maximum value
|
||||
result = exprMaxVal(this)
|
||||
else
|
||||
// We can get the largest value by shifting the largest bound by the smallest bound
|
||||
result = lUpper.bitShiftRight(rLower)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate dependsOnChild(Expr child) {
|
||||
child = getLeftOperand() or child = getLeftOperand()
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
| bitshift.cpp:23:3:23:9 | ... <<= ... | 0.0 | 255.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:25:5:25:11 | ... <<= ... | 0.0 | 255.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:29:3:29:8 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:25:5:25:11 | ... <<= ... | 0.0 | 240.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:29:3:29:8 | ... << ... | 0.0 | 1020.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:32:3:32:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:35:3:35:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:38:3:38:22 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:39:3:39:22 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:40:3:40:22 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:38:3:38:22 | ... << ... | 0.0 | 32640.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:39:3:39:22 | ... << ... | 0.0 | 32640.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:40:3:40:22 | ... << ... | 0.0 | 32640.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:43:3:43:19 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:46:3:46:22 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:46:3:46:22 | ... << ... | 128.0 | 128.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:49:3:49:8 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:52:5:52:10 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:52:5:52:10 | ... << ... | 1.0 | 128.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:57:3:57:8 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:58:3:58:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:59:3:59:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
@@ -17,28 +17,28 @@
|
||||
| bitshift.cpp:61:3:61:19 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:64:3:64:19 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:67:3:67:8 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:70:5:70:10 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:70:5:70:10 | ... << ... | 1.0 | 128.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:75:5:75:10 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:76:5:76:10 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:90:3:90:9 | ... >>= ... | 0.0 | 255.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:92:5:92:11 | ... >>= ... | 0.0 | 255.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:90:3:90:9 | ... >>= ... | 0.0 | 63.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:92:5:92:11 | ... >>= ... | 0.0 | 15.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:96:3:96:8 | ... >> ... | 0.0 | 63.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:99:3:99:9 | ... >> ... | 0.0 | 0.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:103:3:103:9 | ... >> ... | 0.0 | 0.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:106:3:106:22 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:107:3:107:22 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:108:3:108:22 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:106:3:106:22 | ... >> ... | 0.0 | 63.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:107:3:107:22 | ... >> ... | 0.0 | 63.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:108:3:108:22 | ... >> ... | 0.0 | 63.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:111:3:111:19 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:114:3:114:24 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:114:3:114:24 | ... >> ... | 32.0 | 32.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:117:3:117:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:120:5:120:12 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:126:3:126:8 | ... >> ... | -32.0 | 31.0 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:127:3:127:9 | ... >> ... | -1.0 | 0.0 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:120:5:120:12 | ... >> ... | 32.0 | 128.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:126:3:126:8 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:127:3:127:9 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:128:3:128:9 | ... >> ... | -1.0 | 0.0 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:129:3:129:22 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:130:3:130:19 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:133:3:133:21 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:136:3:136:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:139:5:139:12 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:139:5:139:12 | ... >> ... | 32.0 | 128.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:144:5:144:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
| bitshift.cpp:145:5:145:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
import experimental.semmle.code.cpp.rangeanalysis.extensions.ConstantLShiftExprRange
|
||||
import experimental.semmle.code.cpp.rangeanalysis.extensions.ConstantRShiftExprRange
|
||||
|
||||
Expr getLOp(Operation o) {
|
||||
result = o.(BinaryOperation).getLeftOperand() or
|
||||
|
||||
Reference in New Issue
Block a user