@@ -120,7 +120,25 @@ class NarrowedHeapAllocationFunctionCall extends Cast {
120120newtype TArrayAllocation =
121121 TStackAllocation ( ArrayDeclaration arrayDecl ) or
122122 TDynamicAllocation ( NarrowedHeapAllocationFunctionCall narrowedAlloc ) or
123- TAddressOfLvalue ( AddressOfExpr addressExpr )
123+ TAddressOfLvalue ( AddressOfExpr addressExpr ) {
124+ /*
125+ * We'd like to exclude cases such as &arr[1], since that would raise false positives in these cases:
126+ *
127+ * ``` C++
128+ * int arr[4];
129+ * int *third_pos = &arr[2]; // current offset is 2.
130+ * int *one_beyond_last = third_pos + 2; // current offset is 4 (which is just one beyond the last).
131+ * ```
132+ *
133+ * It is totally fine to write (third_pos + 2) in the above case. However, the if we don't make an
134+ * exception on the cases where the address-of operand is an array expression, our query would take
135+ * that as an object of length 1, and (third_pos + 2) will be flagged as an out-of-bound pointer.
136+ *
137+ * c.f. `TAddressOfIndex` branch of `PointerFormation`.
138+ */
139+
140+ not addressExpr .getOperand ( ) instanceof ArrayExpr
141+ }
124142
125143/**
126144 * Any kind of allocation of an array, either allocated on the stack or the heap.
@@ -206,7 +224,24 @@ class IndirectUninitializedNode extends Node {
206224
207225newtype TPointerFormation =
208226 TArrayExpr ( ArrayExprBA arrayExpr ) or
209- TPointerArithmetic ( PointerArithmeticOperation pointerArithmetic )
227+ TPointerArithmetic ( PointerArithmeticOperation pointerArithmetic ) or
228+ TAddressOfIndex ( AddressOfExpr addrOf , ArrayExpr arrExpr ) {
229+ /*
230+ * Here we'd want the array expressions we excluded in `ArrayAllocation`.
231+ *
232+ * ``` C++
233+ * int arr[4];
234+ * int *third_pos = &arr[2]; // current offset is 2.
235+ * int *one_beyond_last = third_pos + 2; // current offset is 4 (which is just one beyond the last).
236+ * ```
237+ *
238+ * &
239+ *
240+ * c.f. `TAddressOfIndex` branch of `PointerFormation`.
241+ */
242+
243+ addrOf .getOperand ( ) = arrExpr
244+ }
210245
211246/**
212247 * Any kind of pointer formation that derives from a base pointer, either as an arithmetic operation
@@ -239,6 +274,10 @@ class PointerFormation extends TPointerFormation {
239274 * Gets the offset of this pointer formation as calculated in relation to the base pointer.
240275 */
241276 int getOffset ( ) {
277+ exists ( ArrayExpr arrExpr | this = TAddressOfIndex ( _, arrExpr ) |
278+ result = arrExpr .getArrayOffset ( ) .getValue ( ) .toInt ( )
279+ )
280+ or
242281 if this .asPointerArithmetic ( ) instanceof PointerSubExpr
243282 then result = - this .getOffsetExpr ( ) .getValue ( ) .toInt ( )
244283 else result = this .getOffsetExpr ( ) .getValue ( ) .toInt ( )
0 commit comments