Skip to content

Commit 92e8604

Browse files
committed
Provide getAllocatedElementType predicate for AllocationExprs.
This predicate tries to determine the type of the allocated elements of an allocation expression.
1 parent 203315a commit 92e8604

File tree

4 files changed

+43
-27
lines changed

4 files changed

+43
-27
lines changed

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

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

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

345+
override Type getAllocatedElementType() {
346+
result = this.getFullyConverted().getUnderlyingType().(PointerType).getBaseType() and
347+
not result instanceof VoidType
348+
}
349+
345350
override predicate requiresDealloc() { target.requiresDealloc() }
346351
}
347352

@@ -353,6 +358,8 @@ class NewAllocationExpr extends AllocationExpr, NewExpr {
353358

354359
override int getSizeBytes() { result = getAllocatedType().getSize() }
355360

361+
override Type getAllocatedElementType() { result = getAllocatedType() }
362+
356363
override predicate requiresDealloc() { not exists(getPlacementPointer()) }
357364
}
358365

@@ -373,6 +380,8 @@ class NewArrayAllocationExpr extends AllocationExpr, NewArrayExpr {
373380
result = getAllocatedElementType().getSize()
374381
}
375382

383+
override Type getAllocatedElementType() { result = NewArrayExpr.super.getAllocatedElementType() }
384+
376385
override int getSizeBytes() { result = getAllocatedType().getSize() }
377386

378387
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.expected

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -61,35 +61,35 @@ 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:157:50:157:55 | call to malloc | getSizeBytes = 5, getSizeExpr = 5, getSizeMult = 1, requiresDealloc |
88+
| allocators.cpp:157:50:157:55 | call to malloc | getAllocatedElementType = const volatile int, getSizeBytes = 5, getSizeExpr = 5, getSizeMult = 1, requiresDealloc |
8989
| allocators.cpp:158:26:158:31 | call to malloc | getSizeBytes = 20, getSizeExpr = 5, getSizeMult = 4, requiresDealloc |
90-
| allocators.cpp:159:31:159:36 | call to malloc | getSizeExpr = count, getSizeMult = 1, requiresDealloc |
91-
| allocators.cpp:160:16:160:21 | call to malloc | getSizeExpr = count, getSizeMult = 4, requiresDealloc |
92-
| allocators.cpp:161:34:161:39 | call to malloc | getSizeExpr = ... + ..., getSizeMult = 1, 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 |
9393
| allocators.cpp:162:23:162:28 | call to malloc | getSizeExpr = count, getSizeMult = 8, requiresDealloc |
9494
| allocators.cpp:163:3:163:8 | call to malloc | getSizeBytes = 32, getSizeExpr = ... * ..., getSizeMult = 1, requiresDealloc |
9595
deallocationFunctions

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)