C#: Introduce control flow exit completions

This commit is contained in:
Tom Hvitved
2018-10-19 12:04:53 +02:00
parent 0c1db6afc3
commit acea4ddfc4
8 changed files with 115 additions and 82 deletions

View File

@@ -59,6 +59,8 @@ private newtype TCompletion =
TGotoDefaultCompletion()
or
TThrowCompletion(ExceptionClass ec)
or
TExitCompletion()
/**
* A completion of a statement or an expression.
@@ -642,3 +644,16 @@ class ThrowCompletion extends Completion, TThrowCompletion {
override string toString() { result = "throw(" + getExceptionClass() + ")" }
}
/**
* A completion that represents evaluation of a statement or an
* expression resulting in a program exit, for example
* `System.Environment.Exit(0)`.
*
* An exit completion is different from a `return` completion; the former
* exits the whole application, and exists inside `try` statements skip
* `finally` blocks.
*/
class ExitCompletion extends Completion, TExitCompletion {
override string toString() { result = "exit" }
}

View File

@@ -785,6 +785,30 @@ module ControlFlow {
c.(ThrowCompletion).getExceptionClass() = getExceptionClass()
}
}
/**
* An exit control flow successor.
*
* Example:
*
* ```
* int M(string s)
* {
* if (s == null)
* System.Environment.Exit(0);
* return s.Length;
* }
* ```
*
* The callable exit node of `M` is an exit successor of the node on line 4.
*/
class ExitSuccessor extends SuccessorType, TExitSuccessor {
override string toString() { result = "exit" }
override predicate matchesCompletion(Completion c) {
c instanceof ExitCompletion
}
}
}
private import SuccessorTypes
@@ -1386,10 +1410,15 @@ module ControlFlow {
result = lastTryStmtFinally(ts, c) and
not c instanceof NormalCompletion
or
// If there is no `finally` block, last elements are from the body, from
// the blocks of one of the `catch` clauses, or from the last `catch` clause
not ts.hasFinally() and
result = getBlockOrCatchFinallyPred(ts, c)
result = getBlockOrCatchFinallyPred(ts, c) and
(
// If there is no `finally` block, last elements are from the body, from
// the blocks of one of the `catch` clauses, or from the last `catch` clause
not ts.hasFinally()
or
// Exit completions ignore the `finally` block
c instanceof ExitCompletion
)
)
or
cfe = any(SpecificCatchClause scc |
@@ -1453,7 +1482,7 @@ module ControlFlow {
// Propagate completion from a call to a non-terminating callable
cfe = any(NonReturningCall nrc |
result = nrc and
c = nrc.getTarget().(NonReturningCallable).getACallCompletion()
c = nrc.getACompletion()
)
}
@@ -1736,17 +1765,31 @@ module ControlFlow {
private import semmle.code.csharp.ExprOrStmtParent
private import semmle.code.csharp.frameworks.System
/**
* A call that definitely does not return (conservative analysis).
*/
class NonReturningCall extends Call {
NonReturningCall() {
this.getTarget() instanceof NonReturningCallable
}
/** A call that definitely does not return (conservative analysis). */
abstract class NonReturningCall extends Call {
/** Gets a valid completion for this non-returning call. */
abstract Completion getACompletion();
}
/** A callable that does not return. */
abstract class NonReturningCallable extends Callable {
private class ExitingCall extends NonReturningCall {
ExitingCall() {
this.getTarget() instanceof ExitingCallable
}
override ExitCompletion getACompletion() { any() }
}
private class ThrowingCall extends NonReturningCall {
private ThrowCompletion c;
ThrowingCall() {
c = this.getTarget().(ThrowingCallable).getACallCompletion()
}
override ThrowCompletion getACompletion() { result = c }
}
private abstract class NonReturningCallable extends Callable {
NonReturningCallable() {
not exists(ReturnStmt ret | ret.getEnclosingCallable() = this) and
not hasAccessorAutoImplementation(this, _) and
@@ -1756,19 +1799,9 @@ module ControlFlow {
v = this.(Accessor).getDeclaration()
)
}
/** Gets a valid completion for a call to this non-returning callable. */
abstract Completion getACallCompletion();
}
/**
* A callable that exits when called.
*/
private abstract class ExitingCallable extends NonReturningCallable {
override Completion getACallCompletion() {
result instanceof ReturnCompletion
}
}
private abstract class ExitingCallable extends NonReturningCallable { }
private class DirectlyExitingCallable extends ExitingCallable {
DirectlyExitingCallable() {
@@ -1789,7 +1822,8 @@ module ControlFlow {
}
private ControlFlowElement getAnExitingElement() {
result.(Call).getTarget() instanceof ExitingCallable or
result instanceof ExitingCall
or
result = getAnExitingStmt()
}
@@ -1805,9 +1839,6 @@ module ControlFlow {
)
}
/**
* A callable that throws an exception when called.
*/
private class ThrowingCallable extends NonReturningCallable {
ThrowingCallable() {
forex(ControlFlowElement body |
@@ -1816,16 +1847,17 @@ module ControlFlow {
)
}
override ThrowCompletion getACallCompletion() {
/** Gets a valid completion for a call to this throwing callable. */
ThrowCompletion getACallCompletion() {
this.getABody() = getAThrowingElement(result)
}
}
private ControlFlowElement getAThrowingElement(ThrowCompletion c) {
c = result.(Call).getTarget().(ThrowingCallable).getACallCompletion()
c = result.(ThrowingCall).getACompletion()
or
result = any(ThrowElement te |
c.(ThrowCompletion).getExceptionClass() = te.getThrownExceptionType() and
c.getExceptionClass() = te.getThrownExceptionType() and
// For stub implementations, there may exist proper implementations that are not seen
// during compilation, so we conservatively rule those out
not isStub(te)
@@ -1839,12 +1871,13 @@ module ControlFlow {
or
result.(BlockStmt).getFirstStmt() = getAThrowingStmt(c)
or
exists(IfStmt ifStmt |
exists(IfStmt ifStmt, ThrowCompletion c1, ThrowCompletion c2 |
result = ifStmt and
ifStmt.getThen() = getAThrowingElement(_) and
ifStmt.getElse() = getAThrowingElement(_) |
ifStmt.getThen() = getAThrowingElement(c) or
ifStmt.getElse() = getAThrowingElement(c)
ifStmt.getThen() = getAThrowingElement(c1) and
ifStmt.getElse() = getAThrowingElement(c2) |
c = c1
or
c = c2
)
}
@@ -2293,6 +2326,7 @@ module ControlFlow {
// Flow from last element of `try` block to first element of `finally` block
cfe = lastTryStmtBlock(ts, c) and
result = first(ts.getFinally()) and
not c instanceof ExitCompletion and
(
c instanceof ThrowCompletion
implies
@@ -3892,6 +3926,8 @@ module ControlFlow {
TExceptionSuccessor(ExceptionClass ec) {
exists(ThrowCompletion c | c.getExceptionClass() = ec)
}
or
TExitSuccessor()
/** Gets a successor node of a given flow type, if any. */
cached

View File

@@ -183,7 +183,7 @@
| ExitMethods.cs:62:19:62:33 | object creation of type Exception | ExitMethods.cs:62:13:62:34 | throw ...; | 2 |
| ExitMethods.cs:64:41:64:43 | "b" | ExitMethods.cs:64:13:64:45 | throw ...; | 3 |
| ExitMethods.cs:67:10:67:13 | enter Exit | ExitMethods.cs:67:10:67:13 | exit Exit | 6 |
| ExitMethods.cs:72:10:72:18 | enter ExitInTry | ExitMethods.cs:72:10:72:18 | exit ExitInTry | 12 |
| ExitMethods.cs:72:10:72:18 | enter ExitInTry | ExitMethods.cs:72:10:72:18 | exit ExitInTry | 8 |
| ExitMethods.cs:85:10:85:24 | enter ApplicationExit | ExitMethods.cs:85:10:85:24 | exit ApplicationExit | 5 |
| ExitMethods.cs:90:13:90:21 | enter ThrowExpr | ExitMethods.cs:92:16:92:25 | ... != ... | 7 |
| ExitMethods.cs:90:13:90:21 | exit ThrowExpr | ExitMethods.cs:90:13:90:21 | exit ThrowExpr | 1 |

View File

@@ -679,17 +679,13 @@
| post | ExitMethods.cs:69:9:69:27 | call to method Exit | ExitMethods.cs:69:26:69:26 | 0 |
| post | ExitMethods.cs:69:9:69:28 | ...; | ExitMethods.cs:68:5:70:5 | {...} |
| post | ExitMethods.cs:69:26:69:26 | 0 | ExitMethods.cs:69:9:69:28 | ...; |
| post | ExitMethods.cs:72:10:72:18 | exit ExitInTry | ExitMethods.cs:81:13:81:40 | [finally: return] call to method WriteLine |
| post | ExitMethods.cs:72:10:72:18 | exit ExitInTry | ExitMethods.cs:76:13:76:18 | call to method Exit |
| post | ExitMethods.cs:73:5:83:5 | {...} | ExitMethods.cs:72:10:72:18 | enter ExitInTry |
| post | ExitMethods.cs:74:9:82:9 | try {...} ... | ExitMethods.cs:73:5:83:5 | {...} |
| post | ExitMethods.cs:75:9:77:9 | {...} | ExitMethods.cs:74:9:82:9 | try {...} ... |
| post | ExitMethods.cs:76:13:76:18 | call to method Exit | ExitMethods.cs:76:13:76:18 | this access |
| post | ExitMethods.cs:76:13:76:18 | this access | ExitMethods.cs:76:13:76:19 | ...; |
| post | ExitMethods.cs:76:13:76:19 | ...; | ExitMethods.cs:75:9:77:9 | {...} |
| post | ExitMethods.cs:79:9:82:9 | [finally: return] {...} | ExitMethods.cs:76:13:76:18 | call to method Exit |
| post | ExitMethods.cs:81:13:81:40 | [finally: return] call to method WriteLine | ExitMethods.cs:81:38:81:39 | [finally: return] "" |
| post | ExitMethods.cs:81:13:81:41 | [finally: return] ...; | ExitMethods.cs:79:9:82:9 | [finally: return] {...} |
| post | ExitMethods.cs:81:38:81:39 | [finally: return] "" | ExitMethods.cs:81:13:81:41 | [finally: return] ...; |
| post | ExitMethods.cs:85:10:85:24 | exit ApplicationExit | ExitMethods.cs:87:9:87:47 | call to method Exit |
| post | ExitMethods.cs:86:5:88:5 | {...} | ExitMethods.cs:85:10:85:24 | enter ApplicationExit |
| post | ExitMethods.cs:87:9:87:47 | call to method Exit | ExitMethods.cs:87:9:87:48 | ...; |
@@ -2826,13 +2822,9 @@
| pre | ExitMethods.cs:73:5:83:5 | {...} | ExitMethods.cs:74:9:82:9 | try {...} ... |
| pre | ExitMethods.cs:74:9:82:9 | try {...} ... | ExitMethods.cs:75:9:77:9 | {...} |
| pre | ExitMethods.cs:75:9:77:9 | {...} | ExitMethods.cs:76:13:76:19 | ...; |
| pre | ExitMethods.cs:76:13:76:18 | call to method Exit | ExitMethods.cs:79:9:82:9 | [finally: return] {...} |
| pre | ExitMethods.cs:76:13:76:18 | call to method Exit | ExitMethods.cs:72:10:72:18 | exit ExitInTry |
| pre | ExitMethods.cs:76:13:76:18 | this access | ExitMethods.cs:76:13:76:18 | call to method Exit |
| pre | ExitMethods.cs:76:13:76:19 | ...; | ExitMethods.cs:76:13:76:18 | this access |
| pre | ExitMethods.cs:79:9:82:9 | [finally: return] {...} | ExitMethods.cs:81:13:81:41 | [finally: return] ...; |
| pre | ExitMethods.cs:81:13:81:40 | [finally: return] call to method WriteLine | ExitMethods.cs:72:10:72:18 | exit ExitInTry |
| pre | ExitMethods.cs:81:13:81:41 | [finally: return] ...; | ExitMethods.cs:81:38:81:39 | [finally: return] "" |
| pre | ExitMethods.cs:81:38:81:39 | [finally: return] "" | ExitMethods.cs:81:13:81:40 | [finally: return] call to method WriteLine |
| pre | ExitMethods.cs:85:10:85:24 | enter ApplicationExit | ExitMethods.cs:86:5:88:5 | {...} |
| pre | ExitMethods.cs:86:5:88:5 | {...} | ExitMethods.cs:87:9:87:48 | ...; |
| pre | ExitMethods.cs:87:9:87:47 | call to method Exit | ExitMethods.cs:85:10:85:24 | exit ApplicationExit |

View File

@@ -520,12 +520,8 @@
| ExitMethods.cs:73:5:83:5 | {...} | ExitMethods.cs:74:9:82:9 | try {...} ... | semmle.label | successor |
| ExitMethods.cs:74:9:82:9 | try {...} ... | ExitMethods.cs:75:9:77:9 | {...} | semmle.label | successor |
| ExitMethods.cs:75:9:77:9 | {...} | ExitMethods.cs:76:13:76:19 | ...; | semmle.label | successor |
| ExitMethods.cs:76:13:76:18 | call to method Exit | ExitMethods.cs:79:9:82:9 | {...} | semmle.label | return |
| ExitMethods.cs:76:13:76:18 | this access | ExitMethods.cs:76:13:76:18 | call to method Exit | semmle.label | successor |
| ExitMethods.cs:76:13:76:19 | ...; | ExitMethods.cs:76:13:76:18 | this access | semmle.label | successor |
| ExitMethods.cs:79:9:82:9 | {...} | ExitMethods.cs:81:13:81:41 | ...; | semmle.label | successor |
| ExitMethods.cs:81:13:81:41 | ...; | ExitMethods.cs:81:38:81:39 | "" | semmle.label | successor |
| ExitMethods.cs:81:38:81:39 | "" | ExitMethods.cs:81:13:81:40 | call to method WriteLine | semmle.label | successor |
| ExitMethods.cs:86:5:88:5 | {...} | ExitMethods.cs:87:9:87:48 | ...; | semmle.label | successor |
| ExitMethods.cs:87:9:87:48 | ...; | ExitMethods.cs:87:9:87:47 | call to method Exit | semmle.label | successor |
| ExitMethods.cs:91:5:93:5 | {...} | ExitMethods.cs:92:16:92:76 | ... ? ... : ... | semmle.label | successor |

View File

@@ -691,17 +691,17 @@
| ExitMethods.cs:21:9:21:26 | ...; | ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | throw(Exception) |
| ExitMethods.cs:21:21:21:24 | true | ExitMethods.cs:21:21:21:24 | true | normal |
| ExitMethods.cs:22:9:22:15 | return ...; | ExitMethods.cs:22:9:22:15 | return ...; | return |
| ExitMethods.cs:26:5:29:5 | {...} | ExitMethods.cs:27:9:27:14 | call to method Exit | return |
| ExitMethods.cs:26:5:29:5 | {...} | ExitMethods.cs:27:9:27:14 | call to method Exit | exit |
| ExitMethods.cs:26:5:29:5 | {...} | ExitMethods.cs:28:9:28:15 | return ...; | return |
| ExitMethods.cs:27:9:27:14 | call to method Exit | ExitMethods.cs:27:9:27:14 | call to method Exit | return |
| ExitMethods.cs:27:9:27:14 | call to method Exit | ExitMethods.cs:27:9:27:14 | call to method Exit | exit |
| ExitMethods.cs:27:9:27:14 | this access | ExitMethods.cs:27:9:27:14 | this access | normal |
| ExitMethods.cs:27:9:27:15 | ...; | ExitMethods.cs:27:9:27:14 | call to method Exit | return |
| ExitMethods.cs:27:9:27:15 | ...; | ExitMethods.cs:27:9:27:14 | call to method Exit | exit |
| ExitMethods.cs:28:9:28:15 | return ...; | ExitMethods.cs:28:9:28:15 | return ...; | return |
| ExitMethods.cs:32:5:35:5 | {...} | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | return |
| ExitMethods.cs:32:5:35:5 | {...} | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | exit |
| ExitMethods.cs:32:5:35:5 | {...} | ExitMethods.cs:34:9:34:15 | return ...; | return |
| ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | return |
| ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | exit |
| ExitMethods.cs:33:9:33:25 | this access | ExitMethods.cs:33:9:33:25 | this access | normal |
| ExitMethods.cs:33:9:33:26 | ...; | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | return |
| ExitMethods.cs:33:9:33:26 | ...; | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | exit |
| ExitMethods.cs:34:9:34:15 | return ...; | ExitMethods.cs:34:9:34:15 | return ...; | return |
| ExitMethods.cs:38:5:51:5 | {...} | ExitMethods.cs:45:13:45:19 | return ...; | return |
| ExitMethods.cs:38:5:51:5 | {...} | ExitMethods.cs:49:13:49:19 | return ...; | return |
@@ -740,23 +740,25 @@
| ExitMethods.cs:64:13:64:45 | throw ...; | ExitMethods.cs:64:13:64:45 | throw ...; | throw(ArgumentException) |
| ExitMethods.cs:64:19:64:44 | object creation of type ArgumentException | ExitMethods.cs:64:19:64:44 | object creation of type ArgumentException | normal |
| ExitMethods.cs:64:41:64:43 | "b" | ExitMethods.cs:64:41:64:43 | "b" | normal |
| ExitMethods.cs:68:5:70:5 | {...} | ExitMethods.cs:69:9:69:27 | call to method Exit | return |
| ExitMethods.cs:69:9:69:27 | call to method Exit | ExitMethods.cs:69:9:69:27 | call to method Exit | return |
| ExitMethods.cs:69:9:69:28 | ...; | ExitMethods.cs:69:9:69:27 | call to method Exit | return |
| ExitMethods.cs:68:5:70:5 | {...} | ExitMethods.cs:69:9:69:27 | call to method Exit | exit |
| ExitMethods.cs:69:9:69:27 | call to method Exit | ExitMethods.cs:69:9:69:27 | call to method Exit | exit |
| ExitMethods.cs:69:9:69:28 | ...; | ExitMethods.cs:69:9:69:27 | call to method Exit | exit |
| ExitMethods.cs:69:26:69:26 | 0 | ExitMethods.cs:69:26:69:26 | 0 | normal |
| ExitMethods.cs:73:5:83:5 | {...} | ExitMethods.cs:81:13:81:40 | call to method WriteLine | return |
| ExitMethods.cs:74:9:82:9 | try {...} ... | ExitMethods.cs:81:13:81:40 | call to method WriteLine | return |
| ExitMethods.cs:75:9:77:9 | {...} | ExitMethods.cs:76:13:76:18 | call to method Exit | return |
| ExitMethods.cs:76:13:76:18 | call to method Exit | ExitMethods.cs:76:13:76:18 | call to method Exit | return |
| ExitMethods.cs:73:5:83:5 | {...} | ExitMethods.cs:76:13:76:18 | call to method Exit | exit |
| ExitMethods.cs:73:5:83:5 | {...} | ExitMethods.cs:81:13:81:40 | call to method WriteLine | exit |
| ExitMethods.cs:74:9:82:9 | try {...} ... | ExitMethods.cs:76:13:76:18 | call to method Exit | exit |
| ExitMethods.cs:74:9:82:9 | try {...} ... | ExitMethods.cs:81:13:81:40 | call to method WriteLine | exit |
| ExitMethods.cs:75:9:77:9 | {...} | ExitMethods.cs:76:13:76:18 | call to method Exit | exit |
| ExitMethods.cs:76:13:76:18 | call to method Exit | ExitMethods.cs:76:13:76:18 | call to method Exit | exit |
| ExitMethods.cs:76:13:76:18 | this access | ExitMethods.cs:76:13:76:18 | this access | normal |
| ExitMethods.cs:76:13:76:19 | ...; | ExitMethods.cs:76:13:76:18 | call to method Exit | return |
| ExitMethods.cs:76:13:76:19 | ...; | ExitMethods.cs:76:13:76:18 | call to method Exit | exit |
| ExitMethods.cs:79:9:82:9 | {...} | ExitMethods.cs:81:13:81:40 | call to method WriteLine | normal |
| ExitMethods.cs:81:13:81:40 | call to method WriteLine | ExitMethods.cs:81:13:81:40 | call to method WriteLine | normal |
| ExitMethods.cs:81:13:81:41 | ...; | ExitMethods.cs:81:13:81:40 | call to method WriteLine | normal |
| ExitMethods.cs:81:38:81:39 | "" | ExitMethods.cs:81:38:81:39 | "" | normal |
| ExitMethods.cs:86:5:88:5 | {...} | ExitMethods.cs:87:9:87:47 | call to method Exit | return |
| ExitMethods.cs:87:9:87:47 | call to method Exit | ExitMethods.cs:87:9:87:47 | call to method Exit | return |
| ExitMethods.cs:87:9:87:48 | ...; | ExitMethods.cs:87:9:87:47 | call to method Exit | return |
| ExitMethods.cs:86:5:88:5 | {...} | ExitMethods.cs:87:9:87:47 | call to method Exit | exit |
| ExitMethods.cs:87:9:87:47 | call to method Exit | ExitMethods.cs:87:9:87:47 | call to method Exit | exit |
| ExitMethods.cs:87:9:87:48 | ...; | ExitMethods.cs:87:9:87:47 | call to method Exit | exit |
| ExitMethods.cs:91:5:93:5 | {...} | ExitMethods.cs:92:9:92:77 | return ...; | return |
| ExitMethods.cs:91:5:93:5 | {...} | ExitMethods.cs:92:41:92:76 | throw ... | throw(ArgumentException) |
| ExitMethods.cs:92:9:92:77 | return ...; | ExitMethods.cs:92:9:92:77 | return ...; | return |

View File

@@ -96,10 +96,6 @@
| CompileTimeOperators.cs:30:9:38:9 | try {...} ... | CompileTimeOperators.cs:37:13:37:40 | [finally: goto(End)] call to method WriteLine |
| CompileTimeOperators.cs:30:9:38:9 | try {...} ... | CompileTimeOperators.cs:37:13:37:41 | [finally: goto(End)] ...; |
| CompileTimeOperators.cs:30:9:38:9 | try {...} ... | CompileTimeOperators.cs:37:31:37:39 | [finally: goto(End)] "Finally" |
| ExitMethods.cs:74:9:82:9 | try {...} ... | ExitMethods.cs:79:9:82:9 | [finally: return] {...} |
| ExitMethods.cs:74:9:82:9 | try {...} ... | ExitMethods.cs:81:13:81:40 | [finally: return] call to method WriteLine |
| ExitMethods.cs:74:9:82:9 | try {...} ... | ExitMethods.cs:81:13:81:41 | [finally: return] ...; |
| ExitMethods.cs:74:9:82:9 | try {...} ... | ExitMethods.cs:81:38:81:39 | [finally: return] "" |
| cflow.cs:148:9:155:9 | try {...} ... | cflow.cs:153:9:155:9 | [finally: exception(Exception)] {...} |
| cflow.cs:148:9:155:9 | try {...} ... | cflow.cs:153:9:155:9 | [finally: exception(OutOfMemoryException)] {...} |
| cflow.cs:148:9:155:9 | try {...} ... | cflow.cs:154:13:154:40 | [finally: exception(Exception)] call to method WriteLine |

View File

@@ -748,12 +748,12 @@
| ExitMethods.cs:21:21:21:24 | true | ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | semmle.label | successor |
| ExitMethods.cs:25:10:25:11 | enter M4 | ExitMethods.cs:26:5:29:5 | {...} | semmle.label | successor |
| ExitMethods.cs:26:5:29:5 | {...} | ExitMethods.cs:27:9:27:15 | ...; | semmle.label | successor |
| ExitMethods.cs:27:9:27:14 | call to method Exit | ExitMethods.cs:25:10:25:11 | exit M4 | semmle.label | return |
| ExitMethods.cs:27:9:27:14 | call to method Exit | ExitMethods.cs:25:10:25:11 | exit M4 | semmle.label | exit |
| ExitMethods.cs:27:9:27:14 | this access | ExitMethods.cs:27:9:27:14 | call to method Exit | semmle.label | successor |
| ExitMethods.cs:27:9:27:15 | ...; | ExitMethods.cs:27:9:27:14 | this access | semmle.label | successor |
| ExitMethods.cs:31:10:31:11 | enter M5 | ExitMethods.cs:32:5:35:5 | {...} | semmle.label | successor |
| ExitMethods.cs:32:5:35:5 | {...} | ExitMethods.cs:33:9:33:26 | ...; | semmle.label | successor |
| ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | ExitMethods.cs:31:10:31:11 | exit M5 | semmle.label | return |
| ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | ExitMethods.cs:31:10:31:11 | exit M5 | semmle.label | exit |
| ExitMethods.cs:33:9:33:25 | this access | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | semmle.label | successor |
| ExitMethods.cs:33:9:33:26 | ...; | ExitMethods.cs:33:9:33:25 | this access | semmle.label | successor |
| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:38:5:51:5 | {...} | semmle.label | successor |
@@ -791,23 +791,19 @@
| ExitMethods.cs:64:41:64:43 | "b" | ExitMethods.cs:64:19:64:44 | object creation of type ArgumentException | semmle.label | successor |
| ExitMethods.cs:67:10:67:13 | enter Exit | ExitMethods.cs:68:5:70:5 | {...} | semmle.label | successor |
| ExitMethods.cs:68:5:70:5 | {...} | ExitMethods.cs:69:9:69:28 | ...; | semmle.label | successor |
| ExitMethods.cs:69:9:69:27 | call to method Exit | ExitMethods.cs:67:10:67:13 | exit Exit | semmle.label | return |
| ExitMethods.cs:69:9:69:27 | call to method Exit | ExitMethods.cs:67:10:67:13 | exit Exit | semmle.label | exit |
| ExitMethods.cs:69:9:69:28 | ...; | ExitMethods.cs:69:26:69:26 | 0 | semmle.label | successor |
| ExitMethods.cs:69:26:69:26 | 0 | ExitMethods.cs:69:9:69:27 | call to method Exit | semmle.label | successor |
| ExitMethods.cs:72:10:72:18 | enter ExitInTry | ExitMethods.cs:73:5:83:5 | {...} | semmle.label | successor |
| ExitMethods.cs:73:5:83:5 | {...} | ExitMethods.cs:74:9:82:9 | try {...} ... | semmle.label | successor |
| ExitMethods.cs:74:9:82:9 | try {...} ... | ExitMethods.cs:75:9:77:9 | {...} | semmle.label | successor |
| ExitMethods.cs:75:9:77:9 | {...} | ExitMethods.cs:76:13:76:19 | ...; | semmle.label | successor |
| ExitMethods.cs:76:13:76:18 | call to method Exit | ExitMethods.cs:79:9:82:9 | [finally: return] {...} | semmle.label | return |
| ExitMethods.cs:76:13:76:18 | call to method Exit | ExitMethods.cs:72:10:72:18 | exit ExitInTry | semmle.label | exit |
| ExitMethods.cs:76:13:76:18 | this access | ExitMethods.cs:76:13:76:18 | call to method Exit | semmle.label | successor |
| ExitMethods.cs:76:13:76:19 | ...; | ExitMethods.cs:76:13:76:18 | this access | semmle.label | successor |
| ExitMethods.cs:79:9:82:9 | [finally: return] {...} | ExitMethods.cs:81:13:81:41 | [finally: return] ...; | semmle.label | successor |
| ExitMethods.cs:81:13:81:40 | [finally: return] call to method WriteLine | ExitMethods.cs:72:10:72:18 | exit ExitInTry | semmle.label | return |
| ExitMethods.cs:81:13:81:41 | [finally: return] ...; | ExitMethods.cs:81:38:81:39 | [finally: return] "" | semmle.label | successor |
| ExitMethods.cs:81:38:81:39 | [finally: return] "" | ExitMethods.cs:81:13:81:40 | [finally: return] call to method WriteLine | semmle.label | successor |
| ExitMethods.cs:85:10:85:24 | enter ApplicationExit | ExitMethods.cs:86:5:88:5 | {...} | semmle.label | successor |
| ExitMethods.cs:86:5:88:5 | {...} | ExitMethods.cs:87:9:87:48 | ...; | semmle.label | successor |
| ExitMethods.cs:87:9:87:47 | call to method Exit | ExitMethods.cs:85:10:85:24 | exit ApplicationExit | semmle.label | return |
| ExitMethods.cs:87:9:87:47 | call to method Exit | ExitMethods.cs:85:10:85:24 | exit ApplicationExit | semmle.label | exit |
| ExitMethods.cs:87:9:87:48 | ...; | ExitMethods.cs:87:9:87:47 | call to method Exit | semmle.label | successor |
| ExitMethods.cs:90:13:90:21 | enter ThrowExpr | ExitMethods.cs:91:5:93:5 | {...} | semmle.label | successor |
| ExitMethods.cs:91:5:93:5 | {...} | ExitMethods.cs:92:16:92:76 | ... ? ... : ... | semmle.label | successor |