Skip to content

Commit e2c5870

Browse files
committed
Checkpoint: Add DynamicAllocation case
1 parent 4464702 commit e2c5870

File tree

2 files changed

+66
-10
lines changed

2 files changed

+66
-10
lines changed

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

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,50 @@ class ArrayDeclaration extends VariableDeclarationEntry {
3333
Expr getInitExpr() { result = this.getVariable().getInitializer().getExpr() }
3434
}
3535

36+
class HeapAllocationFunctionCall extends FunctionCall {
37+
AllocationFunction heapAllocFunction;
38+
39+
HeapAllocationFunctionCall() { this.getTarget() = heapAllocFunction }
40+
41+
predicate isMallocCall() { heapAllocFunction.getName() = "malloc" }
42+
43+
predicate isCallocCall() { heapAllocFunction.getName() = "calloc" }
44+
45+
predicate isReallocCall() { heapAllocFunction.getName() = "realloc" }
46+
47+
abstract Expr getByteArgument();
48+
49+
int getByteLowerBound() { result = lowerBound(this.getByteArgument()) }
50+
}
51+
52+
class MallocFunctionCall extends HeapAllocationFunctionCall {
53+
MallocFunctionCall() { this.isMallocCall() }
54+
55+
override Expr getByteArgument() { result = this.getArgument(0) }
56+
}
57+
58+
class CallocReallocFunctionCall extends HeapAllocationFunctionCall {
59+
CallocReallocFunctionCall() { this.isCallocCall() or this.isReallocCall() }
60+
61+
override Expr getByteArgument() { result = this.getArgument(1) }
62+
}
63+
64+
class NarrowedHeapAllocationFunctionCall extends Cast {
65+
HeapAllocationFunctionCall alloc;
66+
67+
NarrowedHeapAllocationFunctionCall() { alloc = this.getExpr() }
68+
69+
int getMinNumElements() {
70+
result =
71+
alloc.getByteLowerBound() / this.getUnderlyingType().(PointerType).getBaseType().getSize()
72+
}
73+
74+
HeapAllocationFunctionCall getAllocFunctionCall() { result = alloc }
75+
}
76+
3677
newtype TArrayAllocation =
3778
TStackAllocation(ArrayDeclaration arrayDecl) or
38-
TDynamicAllocation(AllocationFunction alloc)
79+
TDynamicAllocation(NarrowedHeapAllocationFunctionCall narrowedAlloc)
3980

4081
newtype TPointerFormation =
4182
TArrayExpr(ArrayExprBA arrayExpr) or
@@ -44,16 +85,20 @@ newtype TPointerFormation =
4485
class ArrayAllocation extends TArrayAllocation {
4586
ArrayDeclaration asStackAllocation() { this = TStackAllocation(result) }
4687

47-
AllocationFunction asDynamicAllocation() { this = TDynamicAllocation(result) }
88+
NarrowedHeapAllocationFunctionCall asDynamicAllocation() { this = TDynamicAllocation(result) }
4889

4990
string toString() {
5091
result = this.asStackAllocation().toString() or
5192
result = this.asDynamicAllocation().toString()
5293
}
5394

95+
/**
96+
* Gets the number of the object that the array holds. This number is exact for a stack-allocated
97+
* array, and the minimum estimated value for a heap-allocated one.
98+
*/
5499
int getLength() {
55100
result = this.asStackAllocation().getLength() or
56-
none() // TODO: this.asDynamicAllocation()
101+
result = this.asDynamicAllocation().getMinNumElements()
57102
}
58103

59104
Location getLocation() {

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

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,29 +43,40 @@ void f2_realloc(int *array) {
4343
int valid1 = array[0]; // COMPLIANT: pointer is within boundary
4444
int valid2 = array[1]; // COMPLIANT: pointer is within boundary
4545
int valid3 = array[2]; // COMPLIANT: pointer points one beyond the last
46-
int invalid1 = array[3]; // NON_COMPLIANT: pointer points one beyond the last
46+
int invalid1 = array[3]; // NON_COMPLIANT: pointer points one beyond the last
4747
// element, but non-compliant to Rule 4.1.3
4848
int invalid2 = array[4]; // NON_COMPLIANT: pointer points more than one beyond
4949
// the last element
5050
int invalid3 = array[-1]; // NON_COMPLIANT: pointer is outside boundary
5151
}
5252

53-
int main() {
53+
int main(int argc, char *argv[]) {
5454
/* 1. Array initialized on the stack */
5555
int array[3] = {0, 1, 2};
5656

5757
f1(array);
5858
f2(array);
5959

6060
/* 2. Array initialized on the heap */
61-
int num_of_elements = 3;
61+
int num_of_elements_malloc;
62+
int num_of_elements_calloc;
63+
int num_of_elements_realloc;
6264

63-
int* array_malloc = (int*)std::malloc(num_of_elements * sizeof(int));
64-
int* array_calloc = (int*)std::calloc(num_of_elements, sizeof(int));
65+
if (argc) {
66+
num_of_elements_malloc = 1;
67+
num_of_elements_calloc = 2;
68+
num_of_elements_realloc = 3;
69+
} else {
70+
num_of_elements_malloc = 4;
71+
num_of_elements_calloc = 5;
72+
num_of_elements_realloc = 6;
73+
}
6574

66-
int new_num_of_elements = 2;
75+
int *array_malloc = (int *)std::malloc(num_of_elements_malloc * sizeof(int));
76+
int *array_calloc = (int *)std::calloc(num_of_elements_calloc, sizeof(int));
6777

68-
int* array_realloc = (int*)std::realloc(array_malloc, new_num_of_elements * sizeof(int));
78+
int *array_realloc =
79+
(int *)std::realloc(array_malloc, num_of_elements_realloc * sizeof(int));
6980

7081
f1(array_malloc);
7182
f2(array_malloc);

0 commit comments

Comments
 (0)