C++: Use SEH exception edges for functions that unconditionally throw those

This commit is contained in:
Jeroen Ketema
2024-12-10 15:01:07 +01:00
parent 0038d0f17c
commit 6f41d3c4e3
5 changed files with 31 additions and 33 deletions

View File

@@ -84,11 +84,10 @@ abstract class TranslatedCall extends TranslatedExpr {
this.getEnclosingFunction().getFunction() = instr.getEnclosingFunction()
)
else (
not this.mustThrowException() and
not this.mustThrowException(_) and
result = this.getParent().getChildSuccessor(this, kind)
or
this.mayThrowException() and
kind instanceof CppExceptionEdge and
this.mayThrowException(kind) and
result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge edge))
)
}
@@ -117,14 +116,14 @@ abstract class TranslatedCall extends TranslatedExpr {
final override Instruction getResult() { result = this.getInstruction(CallTag()) }
/**
* Holds if the evaluation of this call may throw an exception.
* Holds if the evaluation of this call may throw an exception of the kind represented by the `ExceptionEdge`.
*/
abstract predicate mayThrowException();
abstract predicate mayThrowException(ExceptionEdge e);
/**
* Holds if the evaluation of this call always throws an exception.
* Holds if the evaluation of this call always throws an exception of the kind represented by the `ExceptionEdge`.
*/
abstract predicate mustThrowException();
abstract predicate mustThrowException(ExceptionEdge e);
/**
* Gets the result type of the call.
@@ -332,14 +331,14 @@ class TranslatedExprCall extends TranslatedCallExpr {
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
}
final override predicate mayThrowException() {
final override predicate mayThrowException(ExceptionEdge e) {
// We assume that a call to a function pointer will not throw an exception.
// This is not sound in general, but this will greatly reduce the number of
// exceptional edges.
none()
}
final override predicate mustThrowException() { none() }
final override predicate mustThrowException(ExceptionEdge e) { none() }
}
/**
@@ -362,12 +361,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
not exists(MemberFunction func | expr.getTarget() = func and func.isStatic())
}
final override predicate mayThrowException() {
expr.getTarget() instanceof AlwaysSehThrowingFunction
}
final override predicate mayThrowException(ExceptionEdge e) { this.mustThrowException(e) }
final override predicate mustThrowException() {
expr.getTarget() instanceof AlwaysSehThrowingFunction
final override predicate mustThrowException(ExceptionEdge e) {
expr.getTarget() instanceof AlwaysSehThrowingFunction and
e instanceof SehExceptionEdge
}
}

View File

@@ -2483,14 +2483,14 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedDirect
result = getTranslatedExpr(expr.getAllocatorCall().getArgument(index).getFullyConverted())
}
final override predicate mayThrowException() {
final override predicate mayThrowException(ExceptionEdge e) {
// We assume that a call to `new` or `new[]` will never throw. This is not
// sound in general, but this will greatly reduce the number of exceptional
// edges.
none()
}
final override predicate mustThrowException() { none() }
final override predicate mustThrowException(ExceptionEdge e) { none() }
}
TranslatedAllocatorCall getTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) {
@@ -2556,14 +2556,14 @@ class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, Trans
result = getTranslatedExpr(expr.getExprWithReuse().getFullyConverted())
}
final override predicate mayThrowException() {
final override predicate mayThrowException(ExceptionEdge e) {
// We assume that a call to `delete` or `delete[]` will never throw. This is not
// sound in general, but this will greatly reduce the number of exceptional
// edges.
none()
}
final override predicate mustThrowException() { none() }
final override predicate mustThrowException(ExceptionEdge e) { none() }
}
TranslatedDeleteOrDeleteArrayExpr getTranslatedDeleteOrDeleteArray(DeleteOrDeleteArrayExpr newExpr) {

View File

@@ -214,7 +214,7 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
exists(ThrowExpr throw | throw.getEnclosingFunction() = func)
or
exists(FunctionCall call | call.getEnclosingFunction() = func |
getTranslatedExpr(call).(TranslatedCallExpr).mayThrowException()
getTranslatedExpr(call).(TranslatedCallExpr).mayThrowException(_)
)
)
or

View File

@@ -3244,7 +3244,7 @@ ir.c:
# 25| v25_4(void) = Call[ExRaiseAccessViolation] : func:r25_1, 0:r25_3
# 25| m25_5(unknown) = ^CallSideEffect : ~m21_4
# 25| m25_6(unknown) = Chi : total:m21_4, partial:m25_5
#-----| C++ Exception -> Block 3
#-----| SEH Exception -> Block 3
# 26| Block 1
# 26| r26_1(int) = Constant[0] :
@@ -3291,7 +3291,7 @@ ir.c:
# 36| v36_3(void) = Call[ExRaiseAccessViolation] : func:r36_1, 0:r36_2
# 36| m36_4(unknown) = ^CallSideEffect : ~m32_4
# 36| m36_5(unknown) = Chi : total:m32_4, partial:m36_4
#-----| C++ Exception -> Block 4
#-----| SEH Exception -> Block 4
# 32| Block 1
# 32| v32_5(void) = Unwind :
@@ -3326,7 +3326,7 @@ ir.c:
# 40| v40_3(void) = Call[ExRaiseAccessViolation] : func:r40_1, 0:r40_2
# 40| m40_4(unknown) = ^CallSideEffect : ~m36_5
# 40| m40_5(unknown) = Chi : total:m36_5, partial:m40_4
#-----| C++ Exception -> Block 1
#-----| SEH Exception -> Block 1
# 32| Block 6
# 32| v32_8(void) = Unreached :
@@ -3365,7 +3365,7 @@ ir.c:
# 62| v62_3(void) = Call[ExRaiseAccessViolation] : func:r62_1, 0:r62_2
# 62| m62_4(unknown) = ^CallSideEffect : ~m57_4
# 62| m62_5(unknown) = Chi : total:m57_4, partial:m62_4
#-----| C++ Exception -> Block 1
#-----| SEH Exception -> Block 1
# 66| Block 1
# 66| r66_1(int) = Constant[1] :
@@ -3387,7 +3387,7 @@ ir.c:
# 73| v73_3(void) = Call[ExRaiseAccessViolation] : func:r73_1, 0:r73_2
# 73| m73_4(unknown) = ^CallSideEffect : ~m70_4
# 73| m73_5(unknown) = Chi : total:m70_4, partial:m73_4
#-----| C++ Exception -> Block 2
#-----| SEH Exception -> Block 2
# 70| Block 1
# 70| v70_5(void) = Unwind :
@@ -3400,7 +3400,7 @@ ir.c:
# 76| v76_3(void) = Call[ExRaiseAccessViolation] : func:r76_1, 0:r76_2
# 76| m76_4(unknown) = ^CallSideEffect : ~m73_5
# 76| m76_5(unknown) = Chi : total:m73_5, partial:m76_4
#-----| C++ Exception -> Block 1
#-----| SEH Exception -> Block 1
# 80| void raise_access_violation()
# 80| Block 0
@@ -3413,7 +3413,7 @@ ir.c:
# 81| v81_3(void) = Call[ExRaiseAccessViolation] : func:r81_1, 0:r81_2
# 81| m81_4(unknown) = ^CallSideEffect : ~m80_4
# 81| m81_5(unknown) = Chi : total:m80_4, partial:m81_4
#-----| C++ Exception -> Block 1
#-----| SEH Exception -> Block 1
# 80| Block 1
# 80| v80_5(void) = Unwind :

View File

@@ -3000,7 +3000,7 @@ ir.c:
# 25| r25_3(int) = Load[x] : &:r25_2, ~m?
# 25| v25_4(void) = Call[ExRaiseAccessViolation] : func:r25_1, 0:r25_3
# 25| mu25_5(unknown) = ^CallSideEffect : ~m?
#-----| C++ Exception -> Block 6
#-----| SEH Exception -> Block 6
# 21| Block 1
# 21| v21_6(void) = AliasedUse : ~m?
@@ -3057,7 +3057,7 @@ ir.c:
# 36| r36_2(int) = Constant[0] :
# 36| v36_3(void) = Call[ExRaiseAccessViolation] : func:r36_1, 0:r36_2
# 36| mu36_4(unknown) = ^CallSideEffect : ~m?
#-----| C++ Exception -> Block 5
#-----| SEH Exception -> Block 5
# 32| Block 1
# 32| v32_4(void) = AliasedUse : ~m?
@@ -3093,7 +3093,7 @@ ir.c:
# 40| r40_2(int) = Constant[1] :
# 40| v40_3(void) = Call[ExRaiseAccessViolation] : func:r40_1, 0:r40_2
# 40| mu40_4(unknown) = ^CallSideEffect : ~m?
#-----| C++ Exception -> Block 2
#-----| SEH Exception -> Block 2
# 42| Block 7
# 42| v42_1(void) = NoOp :
@@ -3138,7 +3138,7 @@ ir.c:
# 62| r62_2(int) = Constant[0] :
# 62| v62_3(void) = Call[ExRaiseAccessViolation] : func:r62_1, 0:r62_2
# 62| mu62_4(unknown) = ^CallSideEffect : ~m?
#-----| C++ Exception -> Block 3
#-----| SEH Exception -> Block 3
# 57| Block 1
# 57| v57_4(void) = AliasedUse : ~m?
@@ -3165,7 +3165,7 @@ ir.c:
# 73| r73_2(int) = Constant[0] :
# 73| v73_3(void) = Call[ExRaiseAccessViolation] : func:r73_1, 0:r73_2
# 73| mu73_4(unknown) = ^CallSideEffect : ~m?
#-----| C++ Exception -> Block 3
#-----| SEH Exception -> Block 3
# 70| Block 1
# 70| v70_4(void) = AliasedUse : ~m?
@@ -3180,7 +3180,7 @@ ir.c:
# 76| r76_2(int) = Constant[0] :
# 76| v76_3(void) = Call[ExRaiseAccessViolation] : func:r76_1, 0:r76_2
# 76| mu76_4(unknown) = ^CallSideEffect : ~m?
#-----| C++ Exception -> Block 2
#-----| SEH Exception -> Block 2
# 78| Block 4
# 78| v78_1(void) = NoOp :
@@ -3196,7 +3196,7 @@ ir.c:
# 81| r81_2(int) = Constant[1] :
# 81| v81_3(void) = Call[ExRaiseAccessViolation] : func:r81_1, 0:r81_2
# 81| mu81_4(unknown) = ^CallSideEffect : ~m?
#-----| C++ Exception -> Block 2
#-----| SEH Exception -> Block 2
# 80| Block 1
# 80| v80_4(void) = AliasedUse : ~m?