Skip to content

Commit f75f69f

Browse files
committed
Altering unwind SEH mechanics, such that SEH unwind is generated if an SEH exception could be raised inside a microsoft try except statement, or if a function may always throw an exception.
1 parent 4a8f0aa commit f75f69f

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,9 +364,16 @@ abstract class TranslatedCallExpr extends TranslatedNonConstantExpr, TranslatedC
364364
override predicate mayThrowException(ExceptionEdge e) {
365365
// by default, all functions may throw exceptions of any kind
366366
// unless explicitly annotated to never throw
367+
// Only consider a call to "may" throw an Seh exception
368+
// if inside a MicrosoftTryStmt
367369
not this.neverThrowException(e) and
368-
// for now assuming all calls may throw for Seh only
369-
e instanceof SehExceptionEdge
370+
(
371+
this.mustThrowException(e)
372+
or
373+
// for now assuming all calls may throw for Seh only
374+
e instanceof SehExceptionEdge and
375+
exists(MicrosoftTryStmt trystmt | trystmt.getAChild*() = expr)
376+
)
370377
}
371378

372379
override predicate neverThrowException(ExceptionEdge e) {

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ private import TranslatedExpr
1111
private import TranslatedInitialization
1212
private import TranslatedStmt
1313
private import VarArgs
14+
private import EdgeKind
1415

1516
/**
1617
* Gets the `TranslatedFunction` that represents function `func`.
@@ -209,14 +210,16 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
209210
(
210211
// Only generate the `Unwind` instruction if there is any exception
211212
// handling present in the function.
212-
// Do not unwind for MicrosoftTryStmt (SEH), as an optimization (SEH exception
213-
// will occur at any store/load, so unwind would appear everywhere as a result)
214-
exists(TryStmt try | try.getEnclosingFunction() = func)
213+
exists(TryOrMicrosoftTryStmt try | try.getEnclosingFunction() = func)
215214
or
216215
exists(ThrowExpr throw | throw.getEnclosingFunction() = func)
217216
or
218-
exists(FunctionCall call, CppExceptionEdge exception | call.getEnclosingFunction() = func |
219-
getTranslatedExpr(call).(TranslatedCallExpr).mayThrowException(exception)
217+
// or
218+
// exists(FunctionCall call | call.getEnclosingFunction() = func |
219+
// getTranslatedExpr(call).(TranslatedCallExpr).mustThrowException(_)
220+
// )
221+
exists(FunctionCall call | call.getEnclosingFunction() = func |
222+
getTranslatedExpr(call).(TranslatedCallExpr).mayThrowException(_)
220223
)
221224
)
222225
or
@@ -231,9 +234,7 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
231234
}
232235

233236
final override Instruction getExceptionSuccessorInstruction(EdgeKind kind, ExceptionEdge exception) {
234-
// only unwind for C++ exceptions since SEH exceptions are too verbose
235-
// and would generate unwind for all functions.
236-
exception instanceof CppExceptionEdge and
237+
(exception = cppExceptionEdge() or exception = sehExceptionEdge()) and
237238
result = this.getInstruction(UnwindTag()) and
238239
kind instanceof GotoEdge
239240
}

0 commit comments

Comments
 (0)