|
11 | 11 | import cpp |
12 | 12 | import SizeOfTypeUtils |
13 | 13 |
|
| 14 | +predicate isIgnorableBinaryOperation(BinaryOperation op) { |
| 15 | + // FP case: precompilation type checking idiom of the form: |
| 16 | + // sizeof((type *)0 == (ptr)) |
| 17 | + op instanceof EqualityOperation and |
| 18 | + exists(Literal zeroOperand, Expr other, Type t | |
| 19 | + other = op.getAnOperand() and |
| 20 | + other != zeroOperand and |
| 21 | + zeroOperand = op.getAnOperand() and |
| 22 | + zeroOperand.getValue().toInt() = 0 and |
| 23 | + zeroOperand.getImplicitlyConverted().hasExplicitConversion() and |
| 24 | + zeroOperand.getExplicitlyConverted().getUnspecifiedType() = t and |
| 25 | + // often 'NULL' is defined as (void *)0, ignore these cases |
| 26 | + not t instanceof VoidPointerType and |
| 27 | + ( |
| 28 | + // Apparently derived types, eg., functoin pointers, aren't PointerType |
| 29 | + // according to codeql, so special casing them out here. |
| 30 | + other.getUnspecifiedType() instanceof DerivedType |
| 31 | + or |
| 32 | + other.getUnspecifiedType() instanceof PointerType |
| 33 | + ) |
| 34 | + ) |
| 35 | +} |
| 36 | + |
| 37 | +class CandidateOperation extends Operation { |
| 38 | + CandidateOperation() { |
| 39 | + // For now only considering binary operations |
| 40 | + // TODO: Unary operations may be of interest but need special care |
| 41 | + // as pointer deref, and address-of are unary operations. |
| 42 | + // It is therefore more likely to get false positives if unary operations are included. |
| 43 | + // To be considered in the future. |
| 44 | + this instanceof BinaryOperation and |
| 45 | + not isIgnorableBinaryOperation(this) |
| 46 | + } |
| 47 | +} |
| 48 | + |
14 | 49 | from CandidateSizeofCall sizeofExpr, string message, Expr op |
15 | 50 | where |
16 | 51 | exists(string tmpMsg | |
17 | 52 | ( |
18 | | - op instanceof BinaryOperation and tmpMsg = "binary operator" |
| 53 | + op instanceof CandidateOperation and tmpMsg = "binary operator" |
19 | 54 | or |
20 | 55 | op instanceof SizeofOperator and tmpMsg = "sizeof" |
21 | 56 | ) and |
|
0 commit comments