Skip to content

Commit de3fa8e

Browse files
authored
Merge pull request github#3337 from Cornelius-Riemenschneider/alloc-type
C++: Allocation.qll: Provide getAllocatedElementType predicate for AllocationExprs.
2 parents b6a7ab8 + 3f7d681 commit de3fa8e

File tree

5 files changed

+55
-37
lines changed

5 files changed

+55
-37
lines changed

cpp/ql/src/semmle/code/cpp/models/implementations/Allocation.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,12 @@ class CallAllocationExpr extends AllocationExpr, FunctionCall {
342342

343343
override Expr getReallocPtr() { result = getArgument(target.getReallocPtrArg()) }
344344

345+
override Type getAllocatedElementType() {
346+
result =
347+
this.getFullyConverted().getType().stripTopLevelSpecifiers().(PointerType).getBaseType() and
348+
not result instanceof VoidType
349+
}
350+
345351
override predicate requiresDealloc() { target.requiresDealloc() }
346352
}
347353

@@ -353,6 +359,8 @@ class NewAllocationExpr extends AllocationExpr, NewExpr {
353359

354360
override int getSizeBytes() { result = getAllocatedType().getSize() }
355361

362+
override Type getAllocatedElementType() { result = getAllocatedType() }
363+
356364
override predicate requiresDealloc() { not exists(getPlacementPointer()) }
357365
}
358366

@@ -373,6 +381,8 @@ class NewArrayAllocationExpr extends AllocationExpr, NewArrayExpr {
373381
result = getAllocatedElementType().getSize()
374382
}
375383

384+
override Type getAllocatedElementType() { result = NewArrayExpr.super.getAllocatedElementType() }
385+
376386
override int getSizeBytes() { result = getAllocatedType().getSize() }
377387

378388
override predicate requiresDealloc() { not exists(getPlacementPointer()) }

cpp/ql/src/semmle/code/cpp/models/interfaces/Allocation.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ abstract class AllocationExpr extends Expr {
7272
*/
7373
Expr getReallocPtr() { none() }
7474

75+
/**
76+
* Gets the type of the elements that are allocated, if it can be determined.
77+
*/
78+
Type getAllocatedElementType() { none() }
79+
7580
/**
7681
* Whether or not this allocation requires a corresponding deallocation of
7782
* some sort (most do, but `alloca` for example does not). If it is unclear,

cpp/ql/test/library-tests/allocators/allocators.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,14 @@ void directOperatorCall() {
151151
}
152152

153153
void *malloc(size_t);
154+
typedef int* ptr_int;
154155

155156
void testMalloc(size_t count) {
156-
malloc(5);
157-
malloc(5 * sizeof(int));
158-
malloc(count);
159-
malloc(count * sizeof(int));
160-
malloc(count * sizeof(int) + 1);
161-
malloc(((int) count) * sizeof(void *));
162-
malloc(sizeof(void*) * sizeof(int));
157+
const volatile int *i = (const volatile int *) malloc(5);
158+
ptr_int i2 = (ptr_int) malloc(5 * sizeof(int));
159+
volatile long *l = (long *) malloc(count);
160+
l = (long *) malloc(count * sizeof(int));
161+
const char* c = (const char *) malloc(count * sizeof(int) + 1);
162+
void * v = (void *) malloc(((int) count) * sizeof(void *));
163+
malloc(sizeof(void *) * sizeof(int));
163164
}

cpp/ql/test/library-tests/allocators/allocators.expected

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -61,37 +61,37 @@ allocationFunctions
6161
| file://:0:0:0:0 | operator new[] | getSizeArg = 0, requiresDealloc |
6262
| file://:0:0:0:0 | operator new[] | getSizeArg = 0, requiresDealloc |
6363
allocationExprs
64-
| allocators.cpp:49:3:49:9 | new | getSizeBytes = 4, requiresDealloc |
65-
| allocators.cpp:50:3:50:15 | new | getSizeBytes = 4, requiresDealloc |
66-
| allocators.cpp:51:3:51:11 | new | getSizeBytes = 4, requiresDealloc |
67-
| allocators.cpp:52:3:52:14 | new | getSizeBytes = 8, requiresDealloc |
68-
| allocators.cpp:53:3:53:27 | new | getSizeBytes = 8, requiresDealloc |
69-
| allocators.cpp:54:3:54:17 | new | getSizeBytes = 256, requiresDealloc |
70-
| allocators.cpp:55:3:55:25 | new | getSizeBytes = 256, requiresDealloc |
71-
| allocators.cpp:68:3:68:12 | new[] | getSizeExpr = n, getSizeMult = 4, requiresDealloc |
72-
| allocators.cpp:69:3:69:18 | new[] | getSizeExpr = n, getSizeMult = 4, requiresDealloc |
73-
| allocators.cpp:70:3:70:15 | new[] | getSizeExpr = n, getSizeMult = 8, requiresDealloc |
74-
| allocators.cpp:71:3:71:20 | new[] | getSizeExpr = n, getSizeMult = 256, requiresDealloc |
75-
| allocators.cpp:72:3:72:16 | new[] | getSizeBytes = 80, requiresDealloc |
76-
| allocators.cpp:107:3:107:18 | new | getSizeBytes = 1, requiresDealloc |
77-
| allocators.cpp:108:3:108:19 | new[] | getSizeExpr = n, getSizeMult = 1, requiresDealloc |
78-
| allocators.cpp:109:3:109:35 | new | getSizeBytes = 128, requiresDealloc |
79-
| allocators.cpp:110:3:110:37 | new[] | getSizeBytes = 1280, requiresDealloc |
80-
| allocators.cpp:129:3:129:21 | new | getSizeBytes = 4 |
81-
| allocators.cpp:132:3:132:17 | new[] | getSizeBytes = 4 |
82-
| allocators.cpp:135:3:135:26 | new | getSizeBytes = 4, requiresDealloc |
83-
| allocators.cpp:136:3:136:26 | new[] | getSizeBytes = 8, requiresDealloc |
84-
| allocators.cpp:142:13:142:27 | new[] | getSizeExpr = x, getSizeMult = 10, requiresDealloc |
85-
| allocators.cpp:143:13:143:28 | new[] | getSizeBytes = 400, requiresDealloc |
86-
| allocators.cpp:144:13:144:31 | new[] | getSizeExpr = x, getSizeMult = 900, requiresDealloc |
64+
| allocators.cpp:49:3:49:9 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
65+
| allocators.cpp:50:3:50:15 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
66+
| allocators.cpp:51:3:51:11 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
67+
| allocators.cpp:52:3:52:14 | new | getAllocatedElementType = String, getSizeBytes = 8, requiresDealloc |
68+
| allocators.cpp:53:3:53:27 | new | getAllocatedElementType = String, getSizeBytes = 8, requiresDealloc |
69+
| allocators.cpp:54:3:54:17 | new | getAllocatedElementType = Overaligned, getSizeBytes = 256, requiresDealloc |
70+
| allocators.cpp:55:3:55:25 | new | getAllocatedElementType = Overaligned, getSizeBytes = 256, requiresDealloc |
71+
| allocators.cpp:68:3:68:12 | new[] | getAllocatedElementType = int, getSizeExpr = n, getSizeMult = 4, requiresDealloc |
72+
| allocators.cpp:69:3:69:18 | new[] | getAllocatedElementType = int, getSizeExpr = n, getSizeMult = 4, requiresDealloc |
73+
| allocators.cpp:70:3:70:15 | new[] | getAllocatedElementType = String, getSizeExpr = n, getSizeMult = 8, requiresDealloc |
74+
| allocators.cpp:71:3:71:20 | new[] | getAllocatedElementType = Overaligned, getSizeExpr = n, getSizeMult = 256, requiresDealloc |
75+
| allocators.cpp:72:3:72:16 | new[] | getAllocatedElementType = String, getSizeBytes = 80, requiresDealloc |
76+
| allocators.cpp:107:3:107:18 | new | getAllocatedElementType = FailedInit, getSizeBytes = 1, requiresDealloc |
77+
| allocators.cpp:108:3:108:19 | new[] | getAllocatedElementType = FailedInit, getSizeExpr = n, getSizeMult = 1, requiresDealloc |
78+
| allocators.cpp:109:3:109:35 | new | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 128, requiresDealloc |
79+
| allocators.cpp:110:3:110:37 | new[] | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 1280, requiresDealloc |
80+
| allocators.cpp:129:3:129:21 | new | getAllocatedElementType = int, getSizeBytes = 4 |
81+
| allocators.cpp:132:3:132:17 | new[] | getAllocatedElementType = int, getSizeBytes = 4 |
82+
| allocators.cpp:135:3:135:26 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
83+
| allocators.cpp:136:3:136:26 | new[] | getAllocatedElementType = int, getSizeBytes = 8, requiresDealloc |
84+
| allocators.cpp:142:13:142:27 | new[] | getAllocatedElementType = char[10], getSizeExpr = x, getSizeMult = 10, requiresDealloc |
85+
| allocators.cpp:143:13:143:28 | new[] | getAllocatedElementType = char[20], getSizeBytes = 400, requiresDealloc |
86+
| allocators.cpp:144:13:144:31 | new[] | getAllocatedElementType = char[30][30], getSizeExpr = x, getSizeMult = 900, requiresDealloc |
8787
| allocators.cpp:149:8:149:19 | call to operator new | getSizeBytes = 4, getSizeExpr = sizeof(int), getSizeMult = 1, requiresDealloc |
88-
| allocators.cpp:156:3:156:8 | call to malloc | getSizeBytes = 5, getSizeExpr = 5, getSizeMult = 1, requiresDealloc |
89-
| allocators.cpp:157:3:157:8 | call to malloc | getSizeBytes = 20, getSizeExpr = 5, getSizeMult = 4, requiresDealloc |
90-
| allocators.cpp:158:3:158:8 | call to malloc | getSizeExpr = count, getSizeMult = 1, requiresDealloc |
91-
| allocators.cpp:159:3:159:8 | call to malloc | getSizeExpr = count, getSizeMult = 4, requiresDealloc |
92-
| allocators.cpp:160:3:160:8 | call to malloc | getSizeExpr = ... + ..., getSizeMult = 1, requiresDealloc |
93-
| allocators.cpp:161:3:161:8 | call to malloc | getSizeExpr = count, getSizeMult = 8, requiresDealloc |
94-
| allocators.cpp:162:3:162:8 | call to malloc | getSizeBytes = 32, getSizeExpr = ... * ..., getSizeMult = 1, requiresDealloc |
88+
| allocators.cpp:157:50:157:55 | call to malloc | getAllocatedElementType = const volatile int, getSizeBytes = 5, getSizeExpr = 5, getSizeMult = 1, requiresDealloc |
89+
| allocators.cpp:158:26:158:31 | call to malloc | getAllocatedElementType = int, getSizeBytes = 20, getSizeExpr = 5, getSizeMult = 4, requiresDealloc |
90+
| allocators.cpp:159:31:159:36 | call to malloc | getAllocatedElementType = volatile long, getSizeExpr = count, getSizeMult = 1, requiresDealloc |
91+
| allocators.cpp:160:16:160:21 | call to malloc | getAllocatedElementType = volatile long, getSizeExpr = count, getSizeMult = 4, requiresDealloc |
92+
| allocators.cpp:161:34:161:39 | call to malloc | getAllocatedElementType = const char, getSizeExpr = ... + ..., getSizeMult = 1, requiresDealloc |
93+
| allocators.cpp:162:23:162:28 | call to malloc | getSizeExpr = count, getSizeMult = 8, requiresDealloc |
94+
| allocators.cpp:163:3:163:8 | call to malloc | getSizeBytes = 32, getSizeExpr = ... * ..., getSizeMult = 1, requiresDealloc |
9595
deallocationFunctions
9696
| allocators.cpp:11:6:11:20 | operator delete | getFreedArg = 0 |
9797
| allocators.cpp:12:6:12:22 | operator delete[] | getFreedArg = 0 |

cpp/ql/test/library-tests/allocators/allocators.ql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ string describeAllocationExpr(AllocationExpr e) {
138138
or
139139
result = "getReallocPtr = " + e.getReallocPtr().toString()
140140
or
141+
result = "getAllocatedElementType = " + e.getAllocatedElementType().toString()
142+
or
141143
e.requiresDealloc() and
142144
result = "requiresDealloc"
143145
}

0 commit comments

Comments
 (0)