Skip to content

Commit 44ef266

Browse files
committed
Add support for address of arbitrary lvalue exprs
1 parent 9f9d369 commit 44ef266

File tree

2 files changed

+47
-18
lines changed

2 files changed

+47
-18
lines changed

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

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,8 @@ class NarrowedHeapAllocationFunctionCall extends Cast {
119119

120120
newtype TArrayAllocation =
121121
TStackAllocation(ArrayDeclaration arrayDecl) or
122-
TDynamicAllocation(NarrowedHeapAllocationFunctionCall narrowedAlloc)
123-
124-
newtype TPointerFormation =
125-
TArrayExpr(ArrayExprBA arrayExpr) or
126-
TPointerArithmetic(PointerArithmeticOperation pointerArithmetic)
122+
TDynamicAllocation(NarrowedHeapAllocationFunctionCall narrowedAlloc) or
123+
TAddressOfLvalue(AddressOfExpr addressExpr)
127124

128125
/**
129126
* Any kind of allocation of an array, either allocated on the stack or the heap.
@@ -133,9 +130,12 @@ class ArrayAllocation extends TArrayAllocation {
133130

134131
NarrowedHeapAllocationFunctionCall asDynamicAllocation() { this = TDynamicAllocation(result) }
135132

133+
AddressOfExpr asAddressOfExpr() { this = TAddressOfLvalue(result) }
134+
136135
string toString() {
137136
result = this.asStackAllocation().toString() or
138-
result = this.asDynamicAllocation().toString()
137+
result = this.asDynamicAllocation().toString() or
138+
result = this.asAddressOfExpr().toString()
139139
}
140140

141141
/**
@@ -149,26 +149,31 @@ class ArrayAllocation extends TArrayAllocation {
149149
result = this.asStackAllocation().getLength(inode.getIndirection())
150150
)
151151
or
152-
result = this.asStackAllocation().getLength() and
153-
node.asUninitialized() = this.asStackAllocation().getVariable()
152+
node.asUninitialized() = this.asStackAllocation().getVariable() and
153+
result = this.asStackAllocation().getLength()
154154
or
155-
result = this.asDynamicAllocation().getMinNumElements() and
156-
node.asConvertedExpr() = this.asDynamicAllocation()
155+
node.asConvertedExpr() = this.asDynamicAllocation() and
156+
result = this.asDynamicAllocation().getMinNumElements()
157+
or
158+
result = 1 and
159+
node.asExpr() = this.asAddressOfExpr()
157160
}
158161

159162
Location getLocation() {
160163
result = this.asStackAllocation().getLocation() or
161-
result = this.asDynamicAllocation().getLocation()
164+
result = this.asDynamicAllocation().getLocation() or
165+
result = this.asAddressOfExpr().getLocation()
162166
}
163167

164168
/**
165169
* Gets the node associated with this allocation.
166170
*/
167-
DataFlow::Node getNode() { exists(getLength(result)) }
171+
DataFlow::Node getNode() { exists(this.getLength(result)) }
168172

169173
Expr asExpr() {
170174
result = this.asStackAllocation().getVariable().getAnAccess() or
171-
result = this.asDynamicAllocation()
175+
result = this.asDynamicAllocation() or
176+
result = this.asAddressOfExpr()
172177
}
173178
}
174179

@@ -199,6 +204,10 @@ class IndirectUninitializedNode extends Node {
199204
int getIndirection() { result = indirection }
200205
}
201206

207+
newtype TPointerFormation =
208+
TArrayExpr(ArrayExprBA arrayExpr) or
209+
TPointerArithmetic(PointerArithmeticOperation pointerArithmetic)
210+
202211
/**
203212
* Any kind of pointer formation that derives from a base pointer, either as an arithmetic operation
204213
* on pointers, or an array access expression.
@@ -343,11 +352,11 @@ class FatPointer extends TFatPointer {
343352
* ``` C++
344353
* int buf[10];
345354
* int *p = buf;
346-
* int *p2 = p - 5; // offshoots to left, totalOffset = -5
355+
* int *p2 = p - 5; // offshoots to left, totalOffset = -5
347356
* int *p3 = p2 + 16; // offshoots to right, totalOffset = 11
348-
* int *p4 = p3 - 2; // adjusts to left, totalOffset = 9
349-
* int *p5 = p4 - 5; // adjusts to left, totalOffset = 4
350-
* int *p6 = p5 - 5; // offshoots to left, totalOffset = -1
357+
* int *p4 = p3 - 2; // adjusts to left, totalOffset = 9
358+
* int *p5 = p4 - 5; // adjusts to left, totalOffset = 4
359+
* int *p6 = p5 - 5; // offshoots to left, totalOffset = -1
351360
* ```
352361
*
353362
* Then, this table is roughly populated with (we use PathNode src, sink instead of FatPointer

cpp/misra/test/rules/RULE-8-7-1/test.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,22 @@ void stack_allocated_multi_dimensional_pointer_arithmetic(int array[2][3]) {
212212
// one beyond the last element (equivalent to the above)
213213
}
214214

215+
void test_address_of_expr(int *ptr) {
216+
int valid11 = ptr[0]; // COMPLIANT: pointer points one beyond the last element
217+
int *valid12 =
218+
ptr + 0; // COMPLIANT: pointer points one beyond the last element
219+
220+
int valid21 = ptr[1]; // COMPLIANT: pointer points one beyond the last
221+
// element, but non-compliant to Rule 4.1.3
222+
int *valid22 =
223+
ptr + 1; // COMPLIANT: pointer points one beyond the last element
224+
225+
int invalid31 = ptr[2]; // NON_COMPLIANT: pointer points more than one beyond
226+
// the last element
227+
int *invalid32 = ptr + 2; // NON_COMPLIANT: pointer points more than one
228+
// beyond the last element
229+
}
230+
215231
/**
216232
* Test code that was copied from that of ARR38-C, at revision `d82ed6ee`.
217233
*/
@@ -524,13 +540,17 @@ int main(int argc, char *argv[]) {
524540
int stack_multi_dimensional_array[2][3] = {{1, 2, 3}, {4, 5, 6}};
525541

526542
/* 4. Multi-dimensional array initialized on the heap */
527-
int(*heap_multi_dimensional_array)[3] = (int(*)[3])malloc(sizeof(int[2][3]));
543+
int (*heap_multi_dimensional_array)[3] =
544+
(int (*)[3])malloc(sizeof(int[2][3]));
528545

529546
stack_allocated_multi_dimensional_array_access(stack_multi_dimensional_array);
530547
stack_allocated_multi_dimensional_pointer_arithmetic(
531548
stack_multi_dimensional_array);
532549
stack_allocated_multi_dimensional_array_access2(
533550
stack_multi_dimensional_array);
534551

552+
int lvalue_example = 1;
553+
test_address_of_expr(&lvalue_example);
554+
535555
return 0;
536556
}

0 commit comments

Comments
 (0)