Skip to content

Commit 1743ccc

Browse files
committed
C++: Use SEH expection edges for functions that unconditionally throw those
1 parent d657f4f commit 1743ccc

File tree

5 files changed

+31
-33
lines changed

5 files changed

+31
-33
lines changed

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

+12-14
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

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -2375,14 +2375,14 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedDirect
23752375
result = getTranslatedExpr(expr.getAllocatorCall().getArgument(index).getFullyConverted())
23762376
}
23772377

2378-
final override predicate mayThrowException() {
2378+
final override predicate mayThrowException(ExceptionEdge e) {
23792379
// We assume that a call to `new` or `new[]` will never throw. This is not
23802380
// sound in general, but this will greatly reduce the number of exceptional
23812381
// edges.
23822382
none()
23832383
}
23842384

2385-
final override predicate mustThrowException() { none() }
2385+
final override predicate mustThrowException(ExceptionEdge e) { none() }
23862386
}
23872387

23882388
TranslatedAllocatorCall getTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) {
@@ -2448,14 +2448,14 @@ class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, Trans
24482448
result = getTranslatedExpr(expr.getExprWithReuse().getFullyConverted())
24492449
}
24502450

2451-
final override predicate mayThrowException() {
2451+
final override predicate mayThrowException(ExceptionEdge e) {
24522452
// We assume that a call to `delete` or `delete[]` will never throw. This is not
24532453
// sound in general, but this will greatly reduce the number of exceptional
24542454
// edges.
24552455
none()
24562456
}
24572457

2458-
final override predicate mustThrowException() { none() }
2458+
final override predicate mustThrowException(ExceptionEdge e) { none() }
24592459
}
24602460

24612461
TranslatedDeleteOrDeleteArrayExpr getTranslatedDeleteOrDeleteArray(DeleteOrDeleteArrayExpr newExpr) {

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

+1-1
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

Diff for: cpp/ql/test/library-tests/ir/ir/aliased_ir.expected

+7-7
Original file line numberDiff line numberDiff line change
@@ -3120,7 +3120,7 @@ ir.c:
31203120
# 25| v25_4(void) = Call[ExRaiseAccessViolation] : func:r25_1, 0:r25_3
31213121
# 25| m25_5(unknown) = ^CallSideEffect : ~m21_4
31223122
# 25| m25_6(unknown) = Chi : total:m21_4, partial:m25_5
3123-
#-----| C++ Exception -> Block 3
3123+
#-----| SEH Exception -> Block 3
31243124

31253125
# 26| Block 1
31263126
# 26| r26_1(int) = Constant[0] :
@@ -3167,7 +3167,7 @@ ir.c:
31673167
# 36| v36_3(void) = Call[ExRaiseAccessViolation] : func:r36_1, 0:r36_2
31683168
# 36| m36_4(unknown) = ^CallSideEffect : ~m32_4
31693169
# 36| m36_5(unknown) = Chi : total:m32_4, partial:m36_4
3170-
#-----| C++ Exception -> Block 4
3170+
#-----| SEH Exception -> Block 4
31713171

31723172
# 32| Block 1
31733173
# 32| v32_5(void) = Unwind :
@@ -3202,7 +3202,7 @@ ir.c:
32023202
# 40| v40_3(void) = Call[ExRaiseAccessViolation] : func:r40_1, 0:r40_2
32033203
# 40| m40_4(unknown) = ^CallSideEffect : ~m36_5
32043204
# 40| m40_5(unknown) = Chi : total:m36_5, partial:m40_4
3205-
#-----| C++ Exception -> Block 1
3205+
#-----| SEH Exception -> Block 1
32063206

32073207
# 32| Block 6
32083208
# 32| v32_8(void) = Unreached :
@@ -3241,7 +3241,7 @@ ir.c:
32413241
# 62| v62_3(void) = Call[ExRaiseAccessViolation] : func:r62_1, 0:r62_2
32423242
# 62| m62_4(unknown) = ^CallSideEffect : ~m57_4
32433243
# 62| m62_5(unknown) = Chi : total:m57_4, partial:m62_4
3244-
#-----| C++ Exception -> Block 1
3244+
#-----| SEH Exception -> Block 1
32453245

32463246
# 66| Block 1
32473247
# 66| r66_1(int) = Constant[1] :
@@ -3263,7 +3263,7 @@ ir.c:
32633263
# 73| v73_3(void) = Call[ExRaiseAccessViolation] : func:r73_1, 0:r73_2
32643264
# 73| m73_4(unknown) = ^CallSideEffect : ~m70_4
32653265
# 73| m73_5(unknown) = Chi : total:m70_4, partial:m73_4
3266-
#-----| C++ Exception -> Block 2
3266+
#-----| SEH Exception -> Block 2
32673267

32683268
# 70| Block 1
32693269
# 70| v70_5(void) = Unwind :
@@ -3276,7 +3276,7 @@ ir.c:
32763276
# 76| v76_3(void) = Call[ExRaiseAccessViolation] : func:r76_1, 0:r76_2
32773277
# 76| m76_4(unknown) = ^CallSideEffect : ~m73_5
32783278
# 76| m76_5(unknown) = Chi : total:m73_5, partial:m76_4
3279-
#-----| C++ Exception -> Block 1
3279+
#-----| SEH Exception -> Block 1
32803280

32813281
# 80| void raise_access_violation()
32823282
# 80| Block 0
@@ -3289,7 +3289,7 @@ ir.c:
32893289
# 81| v81_3(void) = Call[ExRaiseAccessViolation] : func:r81_1, 0:r81_2
32903290
# 81| m81_4(unknown) = ^CallSideEffect : ~m80_4
32913291
# 81| m81_5(unknown) = Chi : total:m80_4, partial:m81_4
3292-
#-----| C++ Exception -> Block 1
3292+
#-----| SEH Exception -> Block 1
32933293

32943294
# 80| Block 1
32953295
# 80| v80_5(void) = Unwind :

Diff for: cpp/ql/test/library-tests/ir/ir/raw_ir.expected

+7-7
Original file line numberDiff line numberDiff line change
@@ -2884,7 +2884,7 @@ ir.c:
28842884
# 25| r25_3(int) = Load[x] : &:r25_2, ~m?
28852885
# 25| v25_4(void) = Call[ExRaiseAccessViolation] : func:r25_1, 0:r25_3
28862886
# 25| mu25_5(unknown) = ^CallSideEffect : ~m?
2887-
#-----| C++ Exception -> Block 6
2887+
#-----| SEH Exception -> Block 6
28882888

28892889
# 21| Block 1
28902890
# 21| v21_6(void) = AliasedUse : ~m?
@@ -2941,7 +2941,7 @@ ir.c:
29412941
# 36| r36_2(int) = Constant[0] :
29422942
# 36| v36_3(void) = Call[ExRaiseAccessViolation] : func:r36_1, 0:r36_2
29432943
# 36| mu36_4(unknown) = ^CallSideEffect : ~m?
2944-
#-----| C++ Exception -> Block 5
2944+
#-----| SEH Exception -> Block 5
29452945

29462946
# 32| Block 1
29472947
# 32| v32_4(void) = AliasedUse : ~m?
@@ -2977,7 +2977,7 @@ ir.c:
29772977
# 40| r40_2(int) = Constant[1] :
29782978
# 40| v40_3(void) = Call[ExRaiseAccessViolation] : func:r40_1, 0:r40_2
29792979
# 40| mu40_4(unknown) = ^CallSideEffect : ~m?
2980-
#-----| C++ Exception -> Block 2
2980+
#-----| SEH Exception -> Block 2
29812981

29822982
# 42| Block 7
29832983
# 42| v42_1(void) = NoOp :
@@ -3022,7 +3022,7 @@ ir.c:
30223022
# 62| r62_2(int) = Constant[0] :
30233023
# 62| v62_3(void) = Call[ExRaiseAccessViolation] : func:r62_1, 0:r62_2
30243024
# 62| mu62_4(unknown) = ^CallSideEffect : ~m?
3025-
#-----| C++ Exception -> Block 3
3025+
#-----| SEH Exception -> Block 3
30263026

30273027
# 57| Block 1
30283028
# 57| v57_4(void) = AliasedUse : ~m?
@@ -3049,7 +3049,7 @@ ir.c:
30493049
# 73| r73_2(int) = Constant[0] :
30503050
# 73| v73_3(void) = Call[ExRaiseAccessViolation] : func:r73_1, 0:r73_2
30513051
# 73| mu73_4(unknown) = ^CallSideEffect : ~m?
3052-
#-----| C++ Exception -> Block 3
3052+
#-----| SEH Exception -> Block 3
30533053

30543054
# 70| Block 1
30553055
# 70| v70_4(void) = AliasedUse : ~m?
@@ -3064,7 +3064,7 @@ ir.c:
30643064
# 76| r76_2(int) = Constant[0] :
30653065
# 76| v76_3(void) = Call[ExRaiseAccessViolation] : func:r76_1, 0:r76_2
30663066
# 76| mu76_4(unknown) = ^CallSideEffect : ~m?
3067-
#-----| C++ Exception -> Block 2
3067+
#-----| SEH Exception -> Block 2
30683068

30693069
# 78| Block 4
30703070
# 78| v78_1(void) = NoOp :
@@ -3080,7 +3080,7 @@ ir.c:
30803080
# 81| r81_2(int) = Constant[1] :
30813081
# 81| v81_3(void) = Call[ExRaiseAccessViolation] : func:r81_1, 0:r81_2
30823082
# 81| mu81_4(unknown) = ^CallSideEffect : ~m?
3083-
#-----| C++ Exception -> Block 2
3083+
#-----| SEH Exception -> Block 2
30843084

30853085
# 80| Block 1
30863086
# 80| v80_4(void) = AliasedUse : ~m?

0 commit comments

Comments
 (0)