Skip to content

Commit 4f55c77

Browse files
committed
Experiment dealing including / excluding AddressOfExpr
1 parent 7b3569f commit 4f55c77

1 file changed

Lines changed: 41 additions & 2 deletions

File tree

cpp/misra/src/rules/RULE-8-7-1/PointerArithmeticFormsAnInvalidPointer.ql

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,25 @@ class NarrowedHeapAllocationFunctionCall extends Cast {
120120
newtype 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

207225
newtype 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

Comments
 (0)