Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 38 additions & 17 deletions cpp/ql/lib/semmle/code/cpp/ir/implementation/EdgeKind.qll
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
*/

private import internal.EdgeKindInternal
private import codeql.util.Boolean

private newtype TEdgeKind =
TGotoEdge() or // Single successor (including fall-through)
TTrueEdge() or // 'true' edge of conditional branch
TFalseEdge() or // 'false' edge of conditional branch
TExceptionEdge(Boolean isSeh) or // Thrown exception, true for SEH exceptions, false otherwise
TCppExceptionEdge() or // Thrown C++ exception
TSehExceptionEdge() or // Thrown C++ exception
TDefaultEdge() or // 'default' label of switch
TCaseEdge(string minValue, string maxValue) {
// Case label of switch
Expand Down Expand Up @@ -52,23 +52,33 @@ class FalseEdge extends EdgeKindImpl, TFalseEdge {
final override string toString() { result = "False" }
}

abstract private class ExceptionEdgeImpl extends EdgeKindImpl { }

/**
* An "exception" edge, representing the successor of an instruction when that
* instruction's evaluation throws an exception.
*
* Exception edges are expclitly sublcassed to
* `CppExceptionEdge` and `SehExceptionEdge` only.
* Further sublcasses, if required, should be added privately
* here for IR efficiency.
*/
class ExceptionEdge extends EdgeKind, TExceptionEdge {
Boolean isSeh; //true for Structured Exception Handling, false for C++ exceptions

ExceptionEdge() { this = TExceptionEdge(isSeh) }
final class ExceptionEdge = ExceptionEdgeImpl;

/**
* Holds if the exception is a Structured Exception Handling (SEH) exception.
*/
final predicate isSeh() { isSeh = true }
/**
* An "exception" edge, representing the successor of an instruction when that
* instruction's evaluation throws an exception for C++ exceptions
*/
class CppExceptionEdge extends ExceptionEdgeImpl, TCppExceptionEdge {
final override string toString() { result = "C++ Exception" }
}

final override string toString() {
if isSeh = true then result = "SEH Exception" else result = "C++ Exception"
}
/**
* An "exception" edge, representing the successor of an instruction when that
* instruction's evaluation throws an exception for SEH exceptions
*/
class SehExceptionEdge extends ExceptionEdgeImpl, TSehExceptionEdge {
final override string toString() { result = "SEH Exception" }
}

/**
Expand Down Expand Up @@ -135,11 +145,22 @@ module EdgeKind {
FalseEdge falseEdge() { result = TFalseEdge() }

/**
* Gets the single instance of the `ExceptionEdge` class.
* Gets the instance of the `ExceptionEdge` class.
* `isSeh` is true if the exception is an SEH exception, and false for a C++ edge.
* Gets an instance of the `CppExceptionEdge` class.
*/
CppExceptionEdge cppExceptionEdge() { result = TCppExceptionEdge() }

/**
* Gets an instance of the `SehExceptionEdge` class.
*/
ExceptionEdge exceptionEdge(Boolean isSeh) { result = TExceptionEdge(isSeh) }
SehExceptionEdge sehExceptionEdge() { result = TSehExceptionEdge() }

/**
* Gets an instance of the `ExceptionEdge` class.
*/
ExceptionEdge exceptionEdge() {
result = cppExceptionEdge() or
result = sehExceptionEdge()
}

/**
* Gets the single instance of the `DefaultEdge` class.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ abstract class TranslatedCall extends TranslatedExpr {
result = this.getParent().getChildSuccessor(this, kind)
or
this.mayThrowException() and
kind = EdgeKind::exceptionEdge(false) and
kind instanceof CppExceptionEdge and
result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge edge))
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3039,7 +3039,7 @@ class TranslatedDestructorsAfterThrow extends TranslatedElement, TTranslatedDest
or
// And otherwise, exit this element with an exceptional edge
not exists(this.getChild(id + 1)) and
kind = EdgeKind::exceptionEdge(false) and
kind instanceof CppExceptionEdge and
result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge edge))
)
}
Expand Down Expand Up @@ -3078,7 +3078,7 @@ abstract class TranslatedThrowExpr extends TranslatedNonConstantExpr {
result = this.getDestructors().getFirstInstruction(kind)
or
not exists(this.getDestructors()) and
kind = EdgeKind::exceptionEdge(false) and
kind instanceof CppExceptionEdge and
result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge edge))
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ class TranslatedCatchByTypeHandler extends TranslatedHandler {
kind instanceof GotoEdge and
result = this.getParameter().getFirstInstruction(kind)
or
kind = EdgeKind::exceptionEdge(false) and
kind instanceof CppExceptionEdge and
if exists(this.getDestructors())
then result = this.getDestructors().getFirstInstruction(any(GotoEdge edge))
else result = this.getParent().(TranslatedTryStmt).getNextHandler(this, any(GotoEdge edge))
Expand Down
Loading