Merge pull request #523 from jbj/placement-new-never-freed

C++: Detect non-allocating placement new in cpp/memory-never-freed
This commit is contained in:
Geoffrey White
2018-11-23 09:40:11 +00:00
committed by GitHub
8 changed files with 84 additions and 2 deletions

View File

@@ -78,8 +78,8 @@ predicate isStdLibAllocationExpr(Expr e)
*/
predicate isAllocationExpr(Expr e) {
allocationCall(e)
or e instanceof NewExpr
or e instanceof NewArrayExpr
or
e = any(NewOrNewArrayExpr new | not exists(new.getPlacementPointer()))
}
/**

View File

@@ -664,6 +664,16 @@ class NewOrNewArrayExpr extends Expr, @any_new_expr {
* For `new int[5]` the result is `int[5]`.
*/
abstract Type getAllocatedType();
/**
* Gets the pointer `p` if this expression is of the form `new(p) T...`.
* Invocations of this form are non-allocating `new` expressions that may
* call the constructor of `T` but will not allocate memory.
*/
Expr getPlacementPointer() {
isStandardPlacementNewAllocator(this.getAllocator()) and
result = this.getAllocatorCall().getArgument(1)
}
}
/**
@@ -961,3 +971,9 @@ private predicate convparents(Expr child, int idx, Element parent) {
child = astChild.getFullyConverted()
)
}
private predicate isStandardPlacementNewAllocator(Function operatorNew) {
operatorNew.getName().matches("operator new%") and
operatorNew.getNumberOfParameters() = 2 and
operatorNew.getParameter(1).getType() instanceof VoidPointerType
}