mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
CPP: Add delete/delete[] calls to the IR.
This commit is contained in:
@@ -130,6 +130,8 @@ class CallOrAllocationExpr extends Expr {
|
||||
this instanceof Call
|
||||
or
|
||||
this instanceof NewOrNewArrayExpr
|
||||
or
|
||||
this instanceof DeleteOrDeleteArrayExpr
|
||||
}
|
||||
|
||||
/** Gets the `Function` invoked by this expression, if known. */
|
||||
@@ -137,6 +139,8 @@ class CallOrAllocationExpr extends Expr {
|
||||
result = this.(Call).getTarget()
|
||||
or
|
||||
result = this.(NewOrNewArrayExpr).getAllocator()
|
||||
or
|
||||
result = this.(DeleteOrDeleteArrayExpr).getDeallocator()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -350,6 +350,9 @@ class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSi
|
||||
or
|
||||
expr instanceof NewOrNewArrayExpr and
|
||||
result = getTranslatedAllocatorCall(expr).getInstruction(CallTag())
|
||||
or
|
||||
expr instanceof DeleteOrDeleteArrayExpr and
|
||||
result = getTranslatedDeallocatorCall(expr).getInstruction(CallTag())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,19 +75,18 @@ private predicate ignoreExprAndDescendants(Expr expr) {
|
||||
// REVIEW: Ignore initializers for `NewArrayExpr` until we determine how to
|
||||
// represent them.
|
||||
newExpr.getInitializer().getFullyConverted() = expr
|
||||
)
|
||||
) or
|
||||
exists(DeleteOrDeleteArrayExpr deleteExpr |
|
||||
// Ignore the deallocator call, because we always synthesize it.
|
||||
deleteExpr.getDeallocatorCall() = expr
|
||||
)
|
||||
or
|
||||
// Do not translate input/output variables in GNU asm statements
|
||||
// getRealParent(expr) instanceof AsmStmt
|
||||
// or
|
||||
ignoreExprAndDescendants(getRealParent(expr)) // recursive case
|
||||
or
|
||||
// We do not yet translate destructors properly, so for now we ignore any
|
||||
// custom deallocator call, if present.
|
||||
exists(DeleteExpr deleteExpr | deleteExpr.getDeallocatorCall() = expr)
|
||||
or
|
||||
exists(DeleteArrayExpr deleteArrayExpr | deleteArrayExpr.getDeallocatorCall() = expr)
|
||||
or
|
||||
// va_start doesn't evaluate its argument, so we don't need to translate it.
|
||||
exists(BuiltInVarArgsStart vaStartExpr |
|
||||
vaStartExpr.getLastNamedParameter().getFullyConverted() = expr
|
||||
)
|
||||
@@ -104,6 +103,12 @@ private predicate ignoreExprOnly(Expr expr) {
|
||||
newExpr.getAllocatorCall() = expr
|
||||
)
|
||||
or
|
||||
exists(DeleteOrDeleteArrayExpr deleteExpr |
|
||||
// Ignore the destructor call as we don't model it yet. Don't ignore
|
||||
// its arguments, though, as they are the arguments to the deallocator.
|
||||
deleteExpr.getDestructorCall() = expr
|
||||
)
|
||||
or
|
||||
// The extractor deliberately emits an `ErrorExpr` as the first argument to
|
||||
// the allocator call, if any, of a `NewOrNewArrayExpr`. That `ErrorExpr`
|
||||
// should not be translated.
|
||||
@@ -111,13 +116,6 @@ private predicate ignoreExprOnly(Expr expr) {
|
||||
or
|
||||
not translateFunction(getEnclosingFunction(expr)) and
|
||||
not Raw::varHasIRFunc(getEnclosingVariable(expr))
|
||||
or
|
||||
// We do not yet translate destructors properly, so for now we ignore the
|
||||
// destructor call. We do, however, translate the expression being
|
||||
// destructed, and that expression can be a child of the destructor call.
|
||||
exists(DeleteExpr deleteExpr | deleteExpr.getDestructorCall() = expr)
|
||||
or
|
||||
exists(DeleteArrayExpr deleteArrayExpr | deleteArrayExpr.getDestructorCall() = expr)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -724,6 +722,8 @@ newtype TTranslatedElement =
|
||||
} or
|
||||
// An allocator call in a `new` or `new[]` expression
|
||||
TTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) { not ignoreExpr(newExpr) } or
|
||||
// An deallocator call in a `delete` or `delete[]` expression
|
||||
TTranslatedDeallocatorCall(DeleteOrDeleteArrayExpr newExpr) { not ignoreExpr(newExpr) } or
|
||||
// An allocation size for a `new` or `new[]` expression
|
||||
TTranslatedAllocationSize(NewOrNewArrayExpr newExpr) { not ignoreExpr(newExpr) } or
|
||||
// The declaration/initialization part of a `ConditionDeclExpr`
|
||||
|
||||
@@ -2017,6 +2017,48 @@ TranslatedAllocatorCall getTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) {
|
||||
result.getAst() = newExpr
|
||||
}
|
||||
|
||||
/**
|
||||
* The IR translation of a call to `operator delete` as part of a `delete` or `delete[]`
|
||||
* expression.
|
||||
*/
|
||||
class TranslatedDeallocatorCall extends TTranslatedDeallocatorCall, TranslatedDirectCall {
|
||||
override DeleteOrDeleteArrayExpr expr;
|
||||
|
||||
TranslatedDeallocatorCall() { this = TTranslatedDeallocatorCall(expr) }
|
||||
|
||||
final override string toString() { result = "Deallocator call for " + expr.toString() }
|
||||
|
||||
final override predicate producesExprResult() { none() }
|
||||
|
||||
override Function getInstructionFunction(InstructionTag tag) {
|
||||
tag = CallTargetTag() and result = expr.getDeallocator()
|
||||
}
|
||||
|
||||
final override Type getCallResultType() { result = expr.getType() }
|
||||
|
||||
final override TranslatedExpr getQualifier() { none() }
|
||||
|
||||
final override predicate hasArguments() {
|
||||
// All deallocator calls have at least one argument.
|
||||
any()
|
||||
}
|
||||
|
||||
final override int getNumberOfArguments() {
|
||||
// We ignore the other arguments for now as we would have to synthesize them.
|
||||
result = 1
|
||||
}
|
||||
|
||||
final override TranslatedExpr getArgument(int index) {
|
||||
// The only argument we define is the pointer to be deallocated.
|
||||
index = 0 and
|
||||
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
|
||||
}
|
||||
}
|
||||
|
||||
TranslatedDeallocatorCall getTranslatedDeallocatorCall(DeleteOrDeleteArrayExpr newExpr) {
|
||||
result.getAst() = newExpr
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract class implemented by any `TranslatedElement` that has a child
|
||||
* expression that is a call to a constructor or destructor, in order to
|
||||
@@ -2955,75 +2997,60 @@ class TranslatedNewArrayExpr extends TranslatedNewOrNewArrayExpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A placeholder for the translation of a `delete[]` expression.
|
||||
*
|
||||
* Proper translation is not yet implemented, but this stub implementation
|
||||
* ensures that code following a `delete[]` is not unreachable.
|
||||
* The IR translation of a `delete` or `delete[]` expression.
|
||||
*/
|
||||
class TranslatedDeleteArrayExprPlaceHolder extends TranslatedSingleInstructionExpr {
|
||||
override DeleteArrayExpr expr;
|
||||
abstract class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr {
|
||||
override DeleteOrDeleteArrayExpr expr;
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getOperand().getFirstInstruction()
|
||||
final override TranslatedElement getChild(int id) {
|
||||
id = 0 and result = this.getDeallocatorCall()
|
||||
}
|
||||
|
||||
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::Convert and
|
||||
resultType = this.getResultType()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getDeallocatorCall().getFirstInstruction()
|
||||
}
|
||||
|
||||
final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag())
|
||||
child = this.getDeallocatorCall() and result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
none()
|
||||
tag = OnlyInstructionTag() and
|
||||
operandTag instanceof UnaryOperandTag and
|
||||
result = this.getDeallocatorCall().getResult()
|
||||
}
|
||||
|
||||
final override Opcode getOpcode() { result instanceof Opcode::NoOp }
|
||||
|
||||
private TranslatedExpr getOperand() {
|
||||
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
|
||||
private TranslatedDeallocatorCall getDeallocatorCall() {
|
||||
result = getTranslatedDeallocatorCall(expr)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A placeholder for the translation of a `delete` expression.
|
||||
*
|
||||
* Proper translation is not yet implemented, but this stub implementation
|
||||
* ensures that code following a `delete` is not unreachable.
|
||||
* The IR translation of a `delete` expression.
|
||||
*/
|
||||
class TranslatedDeleteExprPlaceHolder extends TranslatedSingleInstructionExpr {
|
||||
class TranslatedDeleteExpr extends TranslatedDeleteOrDeleteArrayExpr {
|
||||
override DeleteExpr expr;
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getOperand().getFirstInstruction()
|
||||
}
|
||||
|
||||
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Opcode getOpcode() { result instanceof Opcode::NoOp }
|
||||
|
||||
private TranslatedExpr getOperand() {
|
||||
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
|
||||
}
|
||||
/**
|
||||
* The IR translation of a `delete[]` expression.
|
||||
*/
|
||||
class TranslatedDeleteArrayExpr extends TranslatedDeleteOrDeleteArrayExpr {
|
||||
override DeleteArrayExpr expr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4887,10 +4887,70 @@
|
||||
| ir.cpp:1011:12:1011:12 | Unary | r1011_3 |
|
||||
| ir.cpp:1015:6:1015:19 | ChiPartial | partial:m1015_3 |
|
||||
| ir.cpp:1015:6:1015:19 | ChiTotal | total:m1015_2 |
|
||||
| ir.cpp:1015:6:1015:19 | SideEffect | m1015_3 |
|
||||
| ir.cpp:1015:6:1015:19 | SideEffect | ~m1020_5 |
|
||||
| ir.cpp:1016:3:1016:35 | CallTarget | func:r1016_1 |
|
||||
| ir.cpp:1016:3:1016:35 | ChiPartial | partial:m1016_4 |
|
||||
| ir.cpp:1016:3:1016:35 | ChiTotal | total:m1015_4 |
|
||||
| ir.cpp:1016:3:1016:35 | SideEffect | ~m1015_4 |
|
||||
| ir.cpp:1016:3:1016:35 | Unary | v1016_3 |
|
||||
| ir.cpp:1016:10:1016:35 | Arg(0) | 0:r1016_2 |
|
||||
| ir.cpp:1017:3:1017:38 | CallTarget | func:r1017_1 |
|
||||
| ir.cpp:1017:3:1017:38 | ChiPartial | partial:m1017_4 |
|
||||
| ir.cpp:1017:3:1017:38 | ChiTotal | total:m1016_5 |
|
||||
| ir.cpp:1017:3:1017:38 | SideEffect | ~m1016_5 |
|
||||
| ir.cpp:1017:3:1017:38 | Unary | v1017_3 |
|
||||
| ir.cpp:1017:10:1017:38 | Arg(0) | 0:r1017_2 |
|
||||
| ir.cpp:1018:3:1018:44 | CallTarget | func:r1018_1 |
|
||||
| ir.cpp:1018:3:1018:44 | ChiPartial | partial:m1018_4 |
|
||||
| ir.cpp:1018:3:1018:44 | ChiTotal | total:m1017_5 |
|
||||
| ir.cpp:1018:3:1018:44 | SideEffect | ~m1017_5 |
|
||||
| ir.cpp:1018:3:1018:44 | Unary | v1018_3 |
|
||||
| ir.cpp:1018:10:1018:44 | Arg(0) | 0:r1018_2 |
|
||||
| ir.cpp:1019:3:1019:43 | CallTarget | func:r1019_1 |
|
||||
| ir.cpp:1019:3:1019:43 | ChiPartial | partial:m1019_4 |
|
||||
| ir.cpp:1019:3:1019:43 | ChiTotal | total:m1018_5 |
|
||||
| ir.cpp:1019:3:1019:43 | SideEffect | ~m1018_5 |
|
||||
| ir.cpp:1019:3:1019:43 | Unary | v1019_3 |
|
||||
| ir.cpp:1019:10:1019:43 | Arg(0) | 0:r1019_2 |
|
||||
| ir.cpp:1020:3:1020:47 | CallTarget | func:r1020_1 |
|
||||
| ir.cpp:1020:3:1020:47 | ChiPartial | partial:m1020_4 |
|
||||
| ir.cpp:1020:3:1020:47 | ChiTotal | total:m1019_5 |
|
||||
| ir.cpp:1020:3:1020:47 | SideEffect | ~m1019_5 |
|
||||
| ir.cpp:1020:3:1020:47 | Unary | v1020_3 |
|
||||
| ir.cpp:1020:10:1020:47 | Arg(0) | 0:r1020_2 |
|
||||
| ir.cpp:1024:6:1024:24 | ChiPartial | partial:m1024_3 |
|
||||
| ir.cpp:1024:6:1024:24 | ChiTotal | total:m1024_2 |
|
||||
| ir.cpp:1024:6:1024:24 | SideEffect | m1024_3 |
|
||||
| ir.cpp:1024:6:1024:24 | SideEffect | ~m1029_5 |
|
||||
| ir.cpp:1025:3:1025:37 | CallTarget | func:r1025_1 |
|
||||
| ir.cpp:1025:3:1025:37 | ChiPartial | partial:m1025_4 |
|
||||
| ir.cpp:1025:3:1025:37 | ChiTotal | total:m1024_4 |
|
||||
| ir.cpp:1025:3:1025:37 | SideEffect | ~m1024_4 |
|
||||
| ir.cpp:1025:3:1025:37 | Unary | v1025_3 |
|
||||
| ir.cpp:1025:12:1025:37 | Arg(0) | 0:r1025_2 |
|
||||
| ir.cpp:1026:3:1026:40 | CallTarget | func:r1026_1 |
|
||||
| ir.cpp:1026:3:1026:40 | ChiPartial | partial:m1026_4 |
|
||||
| ir.cpp:1026:3:1026:40 | ChiTotal | total:m1025_5 |
|
||||
| ir.cpp:1026:3:1026:40 | SideEffect | ~m1025_5 |
|
||||
| ir.cpp:1026:3:1026:40 | Unary | v1026_3 |
|
||||
| ir.cpp:1026:12:1026:40 | Arg(0) | 0:r1026_2 |
|
||||
| ir.cpp:1027:3:1027:46 | CallTarget | func:r1027_1 |
|
||||
| ir.cpp:1027:3:1027:46 | ChiPartial | partial:m1027_4 |
|
||||
| ir.cpp:1027:3:1027:46 | ChiTotal | total:m1026_5 |
|
||||
| ir.cpp:1027:3:1027:46 | SideEffect | ~m1026_5 |
|
||||
| ir.cpp:1027:3:1027:46 | Unary | v1027_3 |
|
||||
| ir.cpp:1027:12:1027:46 | Arg(0) | 0:r1027_2 |
|
||||
| ir.cpp:1028:3:1028:45 | CallTarget | func:r1028_1 |
|
||||
| ir.cpp:1028:3:1028:45 | ChiPartial | partial:m1028_4 |
|
||||
| ir.cpp:1028:3:1028:45 | ChiTotal | total:m1027_5 |
|
||||
| ir.cpp:1028:3:1028:45 | SideEffect | ~m1027_5 |
|
||||
| ir.cpp:1028:3:1028:45 | Unary | v1028_3 |
|
||||
| ir.cpp:1028:12:1028:45 | Arg(0) | 0:r1028_2 |
|
||||
| ir.cpp:1029:3:1029:49 | CallTarget | func:r1029_1 |
|
||||
| ir.cpp:1029:3:1029:49 | ChiPartial | partial:m1029_4 |
|
||||
| ir.cpp:1029:3:1029:49 | ChiTotal | total:m1028_5 |
|
||||
| ir.cpp:1029:3:1029:49 | SideEffect | ~m1028_5 |
|
||||
| ir.cpp:1029:3:1029:49 | Unary | v1029_3 |
|
||||
| ir.cpp:1029:12:1029:49 | Arg(0) | 0:r1029_2 |
|
||||
| ir.cpp:1034:6:1034:20 | ChiPartial | partial:m1034_3 |
|
||||
| ir.cpp:1034:6:1034:20 | ChiTotal | total:m1034_2 |
|
||||
| ir.cpp:1034:6:1034:20 | SideEffect | m1034_3 |
|
||||
|
||||
@@ -5663,43 +5663,73 @@ ir.cpp:
|
||||
|
||||
# 1015| void OperatorDelete()
|
||||
# 1015| Block 0
|
||||
# 1015| v1015_1(void) = EnterFunction :
|
||||
# 1015| mu1015_2(unknown) = AliasedDefinition :
|
||||
# 1015| mu1015_3(unknown) = InitializeNonLocal :
|
||||
# 1016| r1016_1(int *) = Constant[0] :
|
||||
# 1016| v1016_2(void) = NoOp :
|
||||
# 1017| r1017_1(String *) = Constant[0] :
|
||||
# 1017| v1017_2(void) = NoOp :
|
||||
# 1018| r1018_1(SizedDealloc *) = Constant[0] :
|
||||
# 1018| v1018_2(void) = NoOp :
|
||||
# 1019| r1019_1(Overaligned *) = Constant[0] :
|
||||
# 1019| v1019_2(void) = NoOp :
|
||||
# 1020| r1020_1(PolymorphicBase *) = Constant[0] :
|
||||
# 1020| v1020_2(void) = NoOp :
|
||||
# 1021| v1021_1(void) = NoOp :
|
||||
# 1015| v1015_4(void) = ReturnVoid :
|
||||
# 1015| v1015_5(void) = AliasedUse : ~m?
|
||||
# 1015| v1015_6(void) = ExitFunction :
|
||||
# 1015| v1015_1(void) = EnterFunction :
|
||||
# 1015| mu1015_2(unknown) = AliasedDefinition :
|
||||
# 1015| mu1015_3(unknown) = InitializeNonLocal :
|
||||
# 1016| r1016_1(glval<unknown>) = FunctionAddress[operator delete] :
|
||||
# 1016| r1016_2(int *) = Constant[0] :
|
||||
# 1016| v1016_3(void) = Call[operator delete] : func:r1016_1, 0:r1016_2
|
||||
# 1016| mu1016_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1016| v1016_5(void) = Convert : v1016_3
|
||||
# 1017| r1017_1(glval<unknown>) = FunctionAddress[operator delete] :
|
||||
# 1017| r1017_2(String *) = Constant[0] :
|
||||
# 1017| v1017_3(void) = Call[operator delete] : func:r1017_1, 0:r1017_2
|
||||
# 1017| mu1017_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1017| v1017_5(void) = Convert : v1017_3
|
||||
# 1018| r1018_1(glval<unknown>) = FunctionAddress[operator delete] :
|
||||
# 1018| r1018_2(SizedDealloc *) = Constant[0] :
|
||||
# 1018| v1018_3(void) = Call[operator delete] : func:r1018_1, 0:r1018_2
|
||||
# 1018| mu1018_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1018| v1018_5(void) = Convert : v1018_3
|
||||
# 1019| r1019_1(glval<unknown>) = FunctionAddress[operator delete] :
|
||||
# 1019| r1019_2(Overaligned *) = Constant[0] :
|
||||
# 1019| v1019_3(void) = Call[operator delete] : func:r1019_1, 0:r1019_2
|
||||
# 1019| mu1019_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1019| v1019_5(void) = Convert : v1019_3
|
||||
# 1020| r1020_1(glval<unknown>) = FunctionAddress :
|
||||
# 1020| r1020_2(PolymorphicBase *) = Constant[0] :
|
||||
# 1020| v1020_3(void) = Call[?] : func:r1020_1, 0:r1020_2
|
||||
# 1020| mu1020_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1020| v1020_5(void) = Convert : v1020_3
|
||||
# 1021| v1021_1(void) = NoOp :
|
||||
# 1015| v1015_4(void) = ReturnVoid :
|
||||
# 1015| v1015_5(void) = AliasedUse : ~m?
|
||||
# 1015| v1015_6(void) = ExitFunction :
|
||||
|
||||
# 1024| void OperatorDeleteArray()
|
||||
# 1024| Block 0
|
||||
# 1024| v1024_1(void) = EnterFunction :
|
||||
# 1024| mu1024_2(unknown) = AliasedDefinition :
|
||||
# 1024| mu1024_3(unknown) = InitializeNonLocal :
|
||||
# 1025| r1025_1(int *) = Constant[0] :
|
||||
# 1025| v1025_2(void) = NoOp :
|
||||
# 1026| r1026_1(String *) = Constant[0] :
|
||||
# 1026| v1026_2(void) = NoOp :
|
||||
# 1027| r1027_1(SizedDealloc *) = Constant[0] :
|
||||
# 1027| v1027_2(void) = NoOp :
|
||||
# 1028| r1028_1(Overaligned *) = Constant[0] :
|
||||
# 1028| v1028_2(void) = NoOp :
|
||||
# 1029| r1029_1(PolymorphicBase *) = Constant[0] :
|
||||
# 1029| v1029_2(void) = NoOp :
|
||||
# 1030| v1030_1(void) = NoOp :
|
||||
# 1024| v1024_4(void) = ReturnVoid :
|
||||
# 1024| v1024_5(void) = AliasedUse : ~m?
|
||||
# 1024| v1024_6(void) = ExitFunction :
|
||||
# 1024| v1024_1(void) = EnterFunction :
|
||||
# 1024| mu1024_2(unknown) = AliasedDefinition :
|
||||
# 1024| mu1024_3(unknown) = InitializeNonLocal :
|
||||
# 1025| r1025_1(glval<unknown>) = FunctionAddress[operator delete[]] :
|
||||
# 1025| r1025_2(int *) = Constant[0] :
|
||||
# 1025| v1025_3(void) = Call[operator delete[]] : func:r1025_1, 0:r1025_2
|
||||
# 1025| mu1025_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1025| v1025_5(void) = Convert : v1025_3
|
||||
# 1026| r1026_1(glval<unknown>) = FunctionAddress[operator delete[]] :
|
||||
# 1026| r1026_2(String *) = Constant[0] :
|
||||
# 1026| v1026_3(void) = Call[operator delete[]] : func:r1026_1, 0:r1026_2
|
||||
# 1026| mu1026_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1026| v1026_5(void) = Convert : v1026_3
|
||||
# 1027| r1027_1(glval<unknown>) = FunctionAddress[operator delete[]] :
|
||||
# 1027| r1027_2(SizedDealloc *) = Constant[0] :
|
||||
# 1027| v1027_3(void) = Call[operator delete[]] : func:r1027_1, 0:r1027_2
|
||||
# 1027| mu1027_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1027| v1027_5(void) = Convert : v1027_3
|
||||
# 1028| r1028_1(glval<unknown>) = FunctionAddress[operator delete[]] :
|
||||
# 1028| r1028_2(Overaligned *) = Constant[0] :
|
||||
# 1028| v1028_3(void) = Call[operator delete[]] : func:r1028_1, 0:r1028_2
|
||||
# 1028| mu1028_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1028| v1028_5(void) = Convert : v1028_3
|
||||
# 1029| r1029_1(glval<unknown>) = FunctionAddress[operator delete[]] :
|
||||
# 1029| r1029_2(PolymorphicBase *) = Constant[0] :
|
||||
# 1029| v1029_3(void) = Call[operator delete[]] : func:r1029_1, 0:r1029_2
|
||||
# 1029| mu1029_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1029| v1029_5(void) = Convert : v1029_3
|
||||
# 1030| v1030_1(void) = NoOp :
|
||||
# 1024| v1024_4(void) = ReturnVoid :
|
||||
# 1024| v1024_5(void) = AliasedUse : ~m?
|
||||
# 1024| v1024_6(void) = ExitFunction :
|
||||
|
||||
# 1034| void EmptyStructInit()
|
||||
# 1034| Block 0
|
||||
|
||||
@@ -18,6 +18,7 @@ edges
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
|
||||
| test_free.cpp:83:12:83:12 | a | test_free.cpp:85:12:85:12 | a |
|
||||
| test_free.cpp:101:10:101:10 | a | test_free.cpp:103:10:103:10 | a |
|
||||
| test_free.cpp:128:10:128:11 | * ... | test_free.cpp:129:10:129:11 | * ... |
|
||||
| test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a |
|
||||
@@ -51,6 +52,8 @@ nodes
|
||||
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
|
||||
| test_free.cpp:72:14:72:14 | a | semmle.label | a |
|
||||
| test_free.cpp:72:14:72:14 | a | semmle.label | a |
|
||||
| test_free.cpp:83:12:83:12 | a | semmle.label | a |
|
||||
| test_free.cpp:85:12:85:12 | a | semmle.label | a |
|
||||
| test_free.cpp:101:10:101:10 | a | semmle.label | a |
|
||||
| test_free.cpp:103:10:103:10 | a | semmle.label | a |
|
||||
| test_free.cpp:128:10:128:11 | * ... | semmle.label | * ... |
|
||||
@@ -84,6 +87,7 @@ subpaths
|
||||
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
|
||||
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
|
||||
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
|
||||
| test_free.cpp:85:12:85:12 | a | test_free.cpp:83:12:83:12 | a | test_free.cpp:85:12:85:12 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:83:5:83:13 | delete | delete |
|
||||
| test_free.cpp:103:10:103:10 | a | test_free.cpp:101:10:101:10 | a | test_free.cpp:103:10:103:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:101:5:101:8 | call to free | call to free |
|
||||
| test_free.cpp:129:10:129:11 | * ... | test_free.cpp:128:10:128:11 | * ... | test_free.cpp:129:10:129:11 | * ... | Memory pointed to by '* ...' may already have been freed by $@. | test_free.cpp:128:5:128:8 | call to free | call to free |
|
||||
| test_free.cpp:154:10:154:10 | a | test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:152:22:152:25 | call to free | call to free |
|
||||
|
||||
@@ -9,6 +9,7 @@ edges
|
||||
| test_free.cpp:44:27:44:27 | a | test_free.cpp:45:5:45:5 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a |
|
||||
| test_free.cpp:83:12:83:12 | a | test_free.cpp:84:5:84:5 | a |
|
||||
| test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a |
|
||||
| test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a |
|
||||
| test_free.cpp:95:10:95:10 | a | test_free.cpp:96:9:96:9 | a |
|
||||
@@ -41,6 +42,8 @@ nodes
|
||||
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
|
||||
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
|
||||
| test_free.cpp:71:9:71:9 | a | semmle.label | a |
|
||||
| test_free.cpp:83:12:83:12 | a | semmle.label | a |
|
||||
| test_free.cpp:84:5:84:5 | a | semmle.label | a |
|
||||
| test_free.cpp:90:10:90:10 | a | semmle.label | a |
|
||||
| test_free.cpp:90:10:90:10 | a | semmle.label | a |
|
||||
| test_free.cpp:91:5:91:5 | a | semmle.label | a |
|
||||
@@ -75,6 +78,7 @@ subpaths
|
||||
| test_free.cpp:45:5:45:5 | a | test_free.cpp:44:27:44:27 | a | test_free.cpp:45:5:45:5 | a | Memory may have been previously freed by $@. | test_free.cpp:44:22:44:25 | call to free | call to free |
|
||||
| test_free.cpp:71:9:71:9 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a | Memory may have been previously freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
|
||||
| test_free.cpp:71:9:71:9 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a | Memory may have been previously freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
|
||||
| test_free.cpp:84:5:84:5 | a | test_free.cpp:83:12:83:12 | a | test_free.cpp:84:5:84:5 | a | Memory may have been previously freed by $@. | test_free.cpp:83:5:83:13 | delete | delete |
|
||||
| test_free.cpp:91:5:91:5 | a | test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a | Memory may have been previously freed by $@. | test_free.cpp:90:5:90:8 | call to free | call to free |
|
||||
| test_free.cpp:91:5:91:5 | a | test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a | Memory may have been previously freed by $@. | test_free.cpp:90:5:90:8 | call to free | call to free |
|
||||
| test_free.cpp:96:9:96:9 | a | test_free.cpp:95:10:95:10 | a | test_free.cpp:96:9:96:9 | a | Memory may have been previously freed by $@. | test_free.cpp:95:5:95:8 | call to free | call to free |
|
||||
|
||||
@@ -81,8 +81,8 @@ public:
|
||||
void test_new1() {
|
||||
A *a = new A();
|
||||
delete(a);
|
||||
a->f(); // BAD [NOT DETECTED]
|
||||
delete(a); // BAD [NOT DETECTED]
|
||||
a->f(); // BAD
|
||||
delete(a); // BAD
|
||||
}
|
||||
|
||||
void test_dereference1(A *a) {
|
||||
|
||||
@@ -11,6 +11,9 @@ edges
|
||||
| test.cpp:127:7:127:10 | data | test.cpp:130:6:130:9 | data |
|
||||
| test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data |
|
||||
| test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data |
|
||||
| test.cpp:164:9:164:9 | c | test.cpp:165:2:165:2 | c |
|
||||
| test.cpp:164:9:164:9 | c | test.cpp:166:3:166:4 | * ... |
|
||||
| test.cpp:164:9:164:9 | c | test.cpp:166:4:166:4 | c |
|
||||
| test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data |
|
||||
| test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data |
|
||||
| test.cpp:192:7:192:10 | data | test.cpp:197:6:197:9 | data |
|
||||
@@ -19,6 +22,7 @@ edges
|
||||
| test.cpp:203:7:203:10 | data | test.cpp:209:6:209:9 | data |
|
||||
| test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data |
|
||||
| test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data |
|
||||
| test.cpp:216:9:216:9 | x | test.cpp:217:6:217:6 | x |
|
||||
nodes
|
||||
| test.cpp:39:7:39:10 | data | semmle.label | data |
|
||||
| test.cpp:39:7:39:10 | data | semmle.label | data |
|
||||
@@ -38,6 +42,10 @@ nodes
|
||||
| test.cpp:138:7:138:10 | data | semmle.label | data |
|
||||
| test.cpp:138:7:138:10 | data | semmle.label | data |
|
||||
| test.cpp:141:6:141:9 | data | semmle.label | data |
|
||||
| test.cpp:164:9:164:9 | c | semmle.label | c |
|
||||
| test.cpp:165:2:165:2 | c | semmle.label | c |
|
||||
| test.cpp:166:3:166:4 | * ... | semmle.label | * ... |
|
||||
| test.cpp:166:4:166:4 | c | semmle.label | c |
|
||||
| test.cpp:181:7:181:10 | data | semmle.label | data |
|
||||
| test.cpp:181:7:181:10 | data | semmle.label | data |
|
||||
| test.cpp:186:6:186:9 | data | semmle.label | data |
|
||||
@@ -50,6 +58,8 @@ nodes
|
||||
| test.cpp:207:8:207:11 | data | semmle.label | data |
|
||||
| test.cpp:209:6:209:9 | data | semmle.label | data |
|
||||
| test.cpp:209:6:209:9 | data | semmle.label | data |
|
||||
| test.cpp:216:9:216:9 | x | semmle.label | x |
|
||||
| test.cpp:217:6:217:6 | x | semmle.label | x |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:41:6:41:9 | data | test.cpp:39:7:39:10 | data | test.cpp:41:6:41:9 | data | Memory may have been previously freed by $@. | test.cpp:39:2:39:5 | call to free | call to free |
|
||||
@@ -64,6 +74,9 @@ subpaths
|
||||
| test.cpp:130:6:130:9 | data | test.cpp:127:7:127:10 | data | test.cpp:130:6:130:9 | data | Memory may have been previously freed by $@. | test.cpp:127:2:127:5 | call to free | call to free |
|
||||
| test.cpp:141:6:141:9 | data | test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data | Memory may have been previously freed by $@. | test.cpp:138:2:138:5 | call to free | call to free |
|
||||
| test.cpp:141:6:141:9 | data | test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data | Memory may have been previously freed by $@. | test.cpp:138:2:138:5 | call to free | call to free |
|
||||
| test.cpp:165:2:165:2 | c | test.cpp:164:9:164:9 | c | test.cpp:165:2:165:2 | c | Memory may have been previously freed by $@. | test.cpp:164:2:164:10 | delete | delete |
|
||||
| test.cpp:166:3:166:4 | * ... | test.cpp:164:9:164:9 | c | test.cpp:166:3:166:4 | * ... | Memory may have been previously freed by $@. | test.cpp:164:2:164:10 | delete | delete |
|
||||
| test.cpp:166:4:166:4 | c | test.cpp:164:9:164:9 | c | test.cpp:166:4:166:4 | c | Memory may have been previously freed by $@. | test.cpp:164:2:164:10 | delete | delete |
|
||||
| test.cpp:186:6:186:9 | data | test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data | Memory may have been previously freed by $@. | test.cpp:181:2:181:5 | call to free | call to free |
|
||||
| test.cpp:186:6:186:9 | data | test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data | Memory may have been previously freed by $@. | test.cpp:181:2:181:5 | call to free | call to free |
|
||||
| test.cpp:197:6:197:9 | data | test.cpp:192:7:192:10 | data | test.cpp:197:6:197:9 | data | Memory may have been previously freed by $@. | test.cpp:192:2:192:5 | call to free | call to free |
|
||||
@@ -72,3 +85,4 @@ subpaths
|
||||
| test.cpp:209:6:209:9 | data | test.cpp:203:7:203:10 | data | test.cpp:209:6:209:9 | data | Memory may have been previously freed by $@. | test.cpp:203:2:203:5 | call to free | call to free |
|
||||
| test.cpp:209:6:209:9 | data | test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data | Memory may have been previously freed by $@. | test.cpp:207:3:207:6 | call to free | call to free |
|
||||
| test.cpp:209:6:209:9 | data | test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data | Memory may have been previously freed by $@. | test.cpp:207:3:207:6 | call to free | call to free |
|
||||
| test.cpp:217:6:217:6 | x | test.cpp:216:9:216:9 | x | test.cpp:217:6:217:6 | x | Memory may have been previously freed by $@. | test.cpp:216:2:216:9 | delete | delete |
|
||||
|
||||
Reference in New Issue
Block a user