mirror of
https://github.com/github/codeql.git
synced 2025-12-20 18:56:32 +01:00
Merge branch 'master' into ir-flow-fields
This commit is contained in:
@@ -2,6 +2,7 @@ import semmle.code.cpp.Element
|
||||
private import semmle.code.cpp.Enclosing
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
private import semmle.code.cpp.internal.AddressConstantExpression
|
||||
private import semmle.code.cpp.models.implementations.Allocation
|
||||
|
||||
/**
|
||||
* A C/C++ expression.
|
||||
@@ -804,8 +805,10 @@ class NewOrNewArrayExpr extends Expr, @any_new_expr {
|
||||
* call the constructor of `T` but will not allocate memory.
|
||||
*/
|
||||
Expr getPlacementPointer() {
|
||||
isStandardPlacementNewAllocator(this.getAllocator()) and
|
||||
result = this.getAllocatorCall().getArgument(1)
|
||||
result =
|
||||
this
|
||||
.getAllocatorCall()
|
||||
.getArgument(this.getAllocator().(OperatorNewAllocationFunction).getPlacementArgument())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1194,12 +1197,6 @@ private predicate convparents(Expr child, int idx, Element parent) {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isStandardPlacementNewAllocator(Function operatorNew) {
|
||||
operatorNew.getName().matches("operator new%") and
|
||||
operatorNew.getNumberOfParameters() = 2 and
|
||||
operatorNew.getParameter(1).getType() instanceof VoidPointerType
|
||||
}
|
||||
|
||||
// Pulled out for performance. See QL-796.
|
||||
private predicate hasNoConversions(Expr e) { not e.hasConversion() }
|
||||
|
||||
|
||||
@@ -343,6 +343,11 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects {
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
|
||||
expr.getTarget() instanceof AllocationFunction and
|
||||
not exists(NewOrNewArrayExpr newExpr |
|
||||
// we synthesize allocator calls for `new` and `new[]`, so don't add instructions to
|
||||
// the existing allocator call when it exists.
|
||||
newExpr.getAllocatorCall() = expr
|
||||
) and
|
||||
opcode instanceof Opcode::InitializeDynamicAllocation and
|
||||
tag = OnlyInstructionTag() and
|
||||
type = getUnknownType()
|
||||
@@ -358,6 +363,11 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects {
|
||||
tag = OnlyInstructionTag() and
|
||||
kind = gotoEdge() and
|
||||
expr.getTarget() instanceof AllocationFunction and
|
||||
not exists(NewOrNewArrayExpr newExpr |
|
||||
// we synthesize allocator calls for `new` and `new[]`, so don't add instructions to
|
||||
// the existing allocator call when it exists.
|
||||
newExpr.getAllocatorCall() = expr
|
||||
) and
|
||||
if exists(getChild(0))
|
||||
then result = getChild(0).getFirstInstruction()
|
||||
else result = getParent().getChildSuccessor(this)
|
||||
|
||||
@@ -215,6 +215,40 @@ class SizelessAllocationFunction extends AllocationFunction {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An `operator new` or `operator new[]` function that may be associated with `new` or
|
||||
* `new[]` expressions. Note that `new` and `new[]` are not function calls, but these
|
||||
* functions may also be called directly.
|
||||
*/
|
||||
class OperatorNewAllocationFunction extends AllocationFunction {
|
||||
OperatorNewAllocationFunction() {
|
||||
exists(string name |
|
||||
hasGlobalName(name) and
|
||||
(
|
||||
// operator new(bytes, ...)
|
||||
name = "operator new"
|
||||
or
|
||||
// operator new[](bytes, ...)
|
||||
name = "operator new[]"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override int getSizeArg() { result = 0 }
|
||||
|
||||
override predicate requiresDealloc() { not exists(getPlacementArgument()) }
|
||||
|
||||
/**
|
||||
* Gets the position of the placement pointer if this is a placement
|
||||
* `operator new` function.
|
||||
*/
|
||||
int getPlacementArgument() {
|
||||
getNumberOfParameters() = 2 and
|
||||
getParameter(1).getType() instanceof VoidPointerType and
|
||||
result = 1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An allocation expression that is a function call, such as call to `malloc`.
|
||||
*/
|
||||
@@ -227,7 +261,9 @@ class CallAllocationExpr extends AllocationExpr, FunctionCall {
|
||||
not (
|
||||
exists(target.getReallocPtrArg()) and
|
||||
getArgument(target.getSizeArg()).getValue().toInt() = 0
|
||||
)
|
||||
) and
|
||||
// these are modelled directly (and more accurately), avoid duplication
|
||||
not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this)
|
||||
}
|
||||
|
||||
override Expr getSizeExpr() { result = getArgument(target.getSizeArg()) }
|
||||
|
||||
@@ -79,6 +79,28 @@ class StandardDeallocationFunction extends DeallocationFunction {
|
||||
override int getFreedArg() { result = freedArg }
|
||||
}
|
||||
|
||||
/**
|
||||
* An `operator delete` or `operator delete[]` function that may be associated
|
||||
* with `delete` or `delete[]` expressions. Note that `delete` and `delete[]`
|
||||
* are not function calls, but these functions may also be called directly.
|
||||
*/
|
||||
class OperatorDeleteDeallocationFunction extends DeallocationFunction {
|
||||
OperatorDeleteDeallocationFunction() {
|
||||
exists(string name |
|
||||
hasGlobalName(name) and
|
||||
(
|
||||
// operator delete(pointer, ...)
|
||||
name = "operator delete"
|
||||
or
|
||||
// operator delete[](pointer, ...)
|
||||
name = "operator delete[]"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override int getFreedArg() { result = 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* An deallocation expression that is a function call, such as call to `free`.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user