Skip to content

Commit 6f41d3c

Browse files
committed
C++: Use SEH exception edges for functions that unconditionally throw those
1 parent 0038d0f commit 6f41d3c

File tree

5 files changed

+31
-33
lines changed

5 files changed

+31
-33
lines changed

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,10 @@ abstract class TranslatedCall extends TranslatedExpr {
8484
this.getEnclosingFunction().getFunction() = instr.getEnclosingFunction()
8585
)
8686
else (
87-
not this.mustThrowException() and
87+
not this.mustThrowException(_) and
8888
result = this.getParent().getChildSuccessor(this, kind)
8989
or
90-
this.mayThrowException() and
91-
kind instanceof CppExceptionEdge and
90+
this.mayThrowException(kind) and
9291
result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge edge))
9392
)
9493
}
@@ -117,14 +116,14 @@ abstract class TranslatedCall extends TranslatedExpr {
117116
final override Instruction getResult() { result = this.getInstruction(CallTag()) }
118117

119118
/**
120-
* Holds if the evaluation of this call may throw an exception.
119+
* Holds if the evaluation of this call may throw an exception of the kind represented by the `ExceptionEdge`.
121120
*/
122-
abstract predicate mayThrowException();
121+
abstract predicate mayThrowException(ExceptionEdge e);
123122

124123
/**
125-
* Holds if the evaluation of this call always throws an exception.
124+
* Holds if the evaluation of this call always throws an exception of the kind represented by the `ExceptionEdge`.
126125
*/
127-
abstract predicate mustThrowException();
126+
abstract predicate mustThrowException(ExceptionEdge e);
128127

129128
/**
130129
* Gets the result type of the call.
@@ -332,14 +331,14 @@ class TranslatedExprCall extends TranslatedCallExpr {
332331
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
333332
}
334333

335-
final override predicate mayThrowException() {
334+
final override predicate mayThrowException(ExceptionEdge e) {
336335
// We assume that a call to a function pointer will not throw an exception.
337336
// This is not sound in general, but this will greatly reduce the number of
338337
// exceptional edges.
339338
none()
340339
}
341340

342-
final override predicate mustThrowException() { none() }
341+
final override predicate mustThrowException(ExceptionEdge e) { none() }
343342
}
344343

345344
/**
@@ -362,12 +361,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
362361
not exists(MemberFunction func | expr.getTarget() = func and func.isStatic())
363362
}
364363

365-
final override predicate mayThrowException() {
366-
expr.getTarget() instanceof AlwaysSehThrowingFunction
367-
}
364+
final override predicate mayThrowException(ExceptionEdge e) { this.mustThrowException(e) }
368365

369-
final override predicate mustThrowException() {
370-
expr.getTarget() instanceof AlwaysSehThrowingFunction
366+
final override predicate mustThrowException(ExceptionEdge e) {
367+
expr.getTarget() instanceof AlwaysSehThrowingFunction and
368+
e instanceof SehExceptionEdge
371369
}
372370
}
373371

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2483,14 +2483,14 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedDirect
24832483
result = getTranslatedExpr(expr.getAllocatorCall().getArgument(index).getFullyConverted())
24842484
}
24852485

2486-
final override predicate mayThrowException() {
2486+
final override predicate mayThrowException(ExceptionEdge e) {
24872487
// We assume that a call to `new` or `new[]` will never throw. This is not
24882488
// sound in general, but this will greatly reduce the number of exceptional
24892489
// edges.
24902490
none()
24912491
}
24922492

2493-
final override predicate mustThrowException() { none() }
2493+
final override predicate mustThrowException(ExceptionEdge e) { none() }
24942494
}
24952495

24962496
TranslatedAllocatorCall getTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) {
@@ -2556,14 +2556,14 @@ class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, Trans
25562556
result = getTranslatedExpr(expr.getExprWithReuse().getFullyConverted())
25572557
}
25582558

2559-
final override predicate mayThrowException() {
2559+
final override predicate mayThrowException(ExceptionEdge e) {
25602560
// We assume that a call to `delete` or `delete[]` will never throw. This is not
25612561
// sound in general, but this will greatly reduce the number of exceptional
25622562
// edges.
25632563
none()
25642564
}
25652565

2566-
final override predicate mustThrowException() { none() }
2566+
final override predicate mustThrowException(ExceptionEdge e) { none() }
25672567
}
25682568

25692569
TranslatedDeleteOrDeleteArrayExpr getTranslatedDeleteOrDeleteArray(DeleteOrDeleteArrayExpr newExpr) {

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
214214
exists(ThrowExpr throw | throw.getEnclosingFunction() = func)
215215
or
216216
exists(FunctionCall call | call.getEnclosingFunction() = func |
217-
getTranslatedExpr(call).(TranslatedCallExpr).mayThrowException()
217+
getTranslatedExpr(call).(TranslatedCallExpr).mayThrowException(_)
218218
)
219219
)
220220
or

cpp/ql/test/library-tests/ir/ir/aliased_ir.expected

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3244,7 +3244,7 @@ ir.c:
32443244
# 25| v25_4(void) = Call[ExRaiseAccessViolation] : func:r25_1, 0:r25_3
32453245
# 25| m25_5(unknown) = ^CallSideEffect : ~m21_4
32463246
# 25| m25_6(unknown) = Chi : total:m21_4, partial:m25_5
3247-
#-----| C++ Exception -> Block 3
3247+
#-----| SEH Exception -> Block 3
32483248

32493249
# 26| Block 1
32503250
# 26| r26_1(int) = Constant[0] :
@@ -3291,7 +3291,7 @@ ir.c:
32913291
# 36| v36_3(void) = Call[ExRaiseAccessViolation] : func:r36_1, 0:r36_2
32923292
# 36| m36_4(unknown) = ^CallSideEffect : ~m32_4
32933293
# 36| m36_5(unknown) = Chi : total:m32_4, partial:m36_4
3294-
#-----| C++ Exception -> Block 4
3294+
#-----| SEH Exception -> Block 4
32953295

32963296
# 32| Block 1
32973297
# 32| v32_5(void) = Unwind :
@@ -3326,7 +3326,7 @@ ir.c:
33263326
# 40| v40_3(void) = Call[ExRaiseAccessViolation] : func:r40_1, 0:r40_2
33273327
# 40| m40_4(unknown) = ^CallSideEffect : ~m36_5
33283328
# 40| m40_5(unknown) = Chi : total:m36_5, partial:m40_4
3329-
#-----| C++ Exception -> Block 1
3329+
#-----| SEH Exception -> Block 1
33303330

33313331
# 32| Block 6
33323332
# 32| v32_8(void) = Unreached :
@@ -3365,7 +3365,7 @@ ir.c:
33653365
# 62| v62_3(void) = Call[ExRaiseAccessViolation] : func:r62_1, 0:r62_2
33663366
# 62| m62_4(unknown) = ^CallSideEffect : ~m57_4
33673367
# 62| m62_5(unknown) = Chi : total:m57_4, partial:m62_4
3368-
#-----| C++ Exception -> Block 1
3368+
#-----| SEH Exception -> Block 1
33693369

33703370
# 66| Block 1
33713371
# 66| r66_1(int) = Constant[1] :
@@ -3387,7 +3387,7 @@ ir.c:
33873387
# 73| v73_3(void) = Call[ExRaiseAccessViolation] : func:r73_1, 0:r73_2
33883388
# 73| m73_4(unknown) = ^CallSideEffect : ~m70_4
33893389
# 73| m73_5(unknown) = Chi : total:m70_4, partial:m73_4
3390-
#-----| C++ Exception -> Block 2
3390+
#-----| SEH Exception -> Block 2
33913391

33923392
# 70| Block 1
33933393
# 70| v70_5(void) = Unwind :
@@ -3400,7 +3400,7 @@ ir.c:
34003400
# 76| v76_3(void) = Call[ExRaiseAccessViolation] : func:r76_1, 0:r76_2
34013401
# 76| m76_4(unknown) = ^CallSideEffect : ~m73_5
34023402
# 76| m76_5(unknown) = Chi : total:m73_5, partial:m76_4
3403-
#-----| C++ Exception -> Block 1
3403+
#-----| SEH Exception -> Block 1
34043404

34053405
# 80| void raise_access_violation()
34063406
# 80| Block 0
@@ -3413,7 +3413,7 @@ ir.c:
34133413
# 81| v81_3(void) = Call[ExRaiseAccessViolation] : func:r81_1, 0:r81_2
34143414
# 81| m81_4(unknown) = ^CallSideEffect : ~m80_4
34153415
# 81| m81_5(unknown) = Chi : total:m80_4, partial:m81_4
3416-
#-----| C++ Exception -> Block 1
3416+
#-----| SEH Exception -> Block 1
34173417

34183418
# 80| Block 1
34193419
# 80| v80_5(void) = Unwind :

cpp/ql/test/library-tests/ir/ir/raw_ir.expected

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3000,7 +3000,7 @@ ir.c:
30003000
# 25| r25_3(int) = Load[x] : &:r25_2, ~m?
30013001
# 25| v25_4(void) = Call[ExRaiseAccessViolation] : func:r25_1, 0:r25_3
30023002
# 25| mu25_5(unknown) = ^CallSideEffect : ~m?
3003-
#-----| C++ Exception -> Block 6
3003+
#-----| SEH Exception -> Block 6
30043004

30053005
# 21| Block 1
30063006
# 21| v21_6(void) = AliasedUse : ~m?
@@ -3057,7 +3057,7 @@ ir.c:
30573057
# 36| r36_2(int) = Constant[0] :
30583058
# 36| v36_3(void) = Call[ExRaiseAccessViolation] : func:r36_1, 0:r36_2
30593059
# 36| mu36_4(unknown) = ^CallSideEffect : ~m?
3060-
#-----| C++ Exception -> Block 5
3060+
#-----| SEH Exception -> Block 5
30613061

30623062
# 32| Block 1
30633063
# 32| v32_4(void) = AliasedUse : ~m?
@@ -3093,7 +3093,7 @@ ir.c:
30933093
# 40| r40_2(int) = Constant[1] :
30943094
# 40| v40_3(void) = Call[ExRaiseAccessViolation] : func:r40_1, 0:r40_2
30953095
# 40| mu40_4(unknown) = ^CallSideEffect : ~m?
3096-
#-----| C++ Exception -> Block 2
3096+
#-----| SEH Exception -> Block 2
30973097

30983098
# 42| Block 7
30993099
# 42| v42_1(void) = NoOp :
@@ -3138,7 +3138,7 @@ ir.c:
31383138
# 62| r62_2(int) = Constant[0] :
31393139
# 62| v62_3(void) = Call[ExRaiseAccessViolation] : func:r62_1, 0:r62_2
31403140
# 62| mu62_4(unknown) = ^CallSideEffect : ~m?
3141-
#-----| C++ Exception -> Block 3
3141+
#-----| SEH Exception -> Block 3
31423142

31433143
# 57| Block 1
31443144
# 57| v57_4(void) = AliasedUse : ~m?
@@ -3165,7 +3165,7 @@ ir.c:
31653165
# 73| r73_2(int) = Constant[0] :
31663166
# 73| v73_3(void) = Call[ExRaiseAccessViolation] : func:r73_1, 0:r73_2
31673167
# 73| mu73_4(unknown) = ^CallSideEffect : ~m?
3168-
#-----| C++ Exception -> Block 3
3168+
#-----| SEH Exception -> Block 3
31693169

31703170
# 70| Block 1
31713171
# 70| v70_4(void) = AliasedUse : ~m?
@@ -3180,7 +3180,7 @@ ir.c:
31803180
# 76| r76_2(int) = Constant[0] :
31813181
# 76| v76_3(void) = Call[ExRaiseAccessViolation] : func:r76_1, 0:r76_2
31823182
# 76| mu76_4(unknown) = ^CallSideEffect : ~m?
3183-
#-----| C++ Exception -> Block 2
3183+
#-----| SEH Exception -> Block 2
31843184

31853185
# 78| Block 4
31863186
# 78| v78_1(void) = NoOp :
@@ -3196,7 +3196,7 @@ ir.c:
31963196
# 81| r81_2(int) = Constant[1] :
31973197
# 81| v81_3(void) = Call[ExRaiseAccessViolation] : func:r81_1, 0:r81_2
31983198
# 81| mu81_4(unknown) = ^CallSideEffect : ~m?
3199-
#-----| C++ Exception -> Block 2
3199+
#-----| SEH Exception -> Block 2
32003200

32013201
# 80| Block 1
32023202
# 80| v80_4(void) = AliasedUse : ~m?

0 commit comments

Comments
 (0)