Skip to content

Commit d308178

Browse files
committed
C++: Add extensible predicate for allocation.
1 parent ce5ab4c commit d308178

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,63 @@ private class NewArrayAllocationExpr extends AllocationExpr, NewArrayExpr {
373373
override predicate requiresDealloc() { not exists(this.getPlacementPointer()) }
374374
}
375375

376+
/**
377+
* Holds if `f` is an allocation function according to the
378+
* extensible `allocationFunctionModel` predicate.
379+
*/
380+
private predicate isAllocationFunctionFromModel(
381+
Function f, string namespace, string type, string name
382+
) {
383+
exists(boolean subtypes | allocationFunctionModel(namespace, type, subtypes, name, _, _, _, _) |
384+
if type = ""
385+
then f.hasQualifiedName(namespace, "", name)
386+
else
387+
exists(Class c |
388+
c.hasQualifiedName(namespace, type) and f.hasQualifiedName(namespace, _, name)
389+
|
390+
if subtypes = true
391+
then f = c.getADerivedClass*().getAMemberFunction()
392+
else f = c.getAMemberFunction()
393+
)
394+
)
395+
}
396+
397+
/**
398+
* An allocation function modeled via the extensible `allocationFunctionModel` predicate.
399+
*/
400+
private class AllocationFunctionFromModel extends AllocationFunction {
401+
string namespace;
402+
string type;
403+
string name;
404+
405+
AllocationFunctionFromModel() { isAllocationFunctionFromModel(this, namespace, type, name) }
406+
407+
final override int getSizeArg() {
408+
exists(string sizeArg |
409+
allocationFunctionModel(namespace, type, _, name, sizeArg, _, _, _) and
410+
result = sizeArg.toInt()
411+
)
412+
}
413+
414+
final override int getSizeMult() {
415+
exists(string sizeMult |
416+
allocationFunctionModel(namespace, type, _, name, _, sizeMult, _, _) and
417+
result = sizeMult.toInt()
418+
)
419+
}
420+
421+
final override int getReallocPtrArg() {
422+
exists(string reallocPtrArg |
423+
allocationFunctionModel(namespace, type, _, name, _, _, reallocPtrArg, _) and
424+
result = reallocPtrArg.toInt()
425+
)
426+
}
427+
428+
final override predicate requiresDealloc() {
429+
allocationFunctionModel(namespace, type, _, name, _, _, _, true)
430+
}
431+
}
432+
376433
private module HeuristicAllocation {
377434
/** A class that maps an `AllocationExpr` to an `HeuristicAllocationExpr`. */
378435
private class HeuristicAllocationModeled extends HeuristicAllocationExpr instanceof AllocationExpr

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ abstract class AllocationFunction extends Function {
8989
predicate requiresDealloc() { any() }
9090
}
9191

92+
/**
93+
* Holds if an external allocation model exists for the given parameters.
94+
*/
95+
extensible predicate allocationFunctionModel(
96+
string namespace, string type, boolean subtypes, string name, string sizeArg, string multArg,
97+
string reallocPtrArg, boolean requiresDealloc
98+
);
99+
92100
/**
93101
* An `operator new` or `operator new[]` function that may be associated with
94102
* `new` or `new[]` expressions. Note that `new` and `new[]` are not function

0 commit comments

Comments
 (0)