From 4800464ed6191d4ba8b99fb790b60aa3de6398bb Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 3 Oct 2016 11:03:28 -0700 Subject: [PATCH] do not reset current flow after processing finally block if it was unreachable (#11310) * do not reset current flow after processing finally block if it was unreachable * fix tests --- src/compiler/binder.ts | 6 ++++- .../reference/unreachableFlowAfterFinally.js | 27 +++++++++++++++++++ .../unreachableFlowAfterFinally.symbols | 20 ++++++++++++++ .../unreachableFlowAfterFinally.types | 22 +++++++++++++++ .../compiler/unreachableFlowAfterFinally.ts | 14 ++++++++++ 5 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/unreachableFlowAfterFinally.js create mode 100644 tests/baselines/reference/unreachableFlowAfterFinally.symbols create mode 100644 tests/baselines/reference/unreachableFlowAfterFinally.types create mode 100644 tests/cases/compiler/unreachableFlowAfterFinally.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e2d31162127..2fe7d30ab56 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -964,7 +964,11 @@ namespace ts { currentFlow = preTryFlow; bind(node.finallyBlock); } - currentFlow = finishFlowLabel(postFinallyLabel); + // if try statement has finally block and flow after finally block is unreachable - keep it + // otherwise use whatever flow was accumulated at postFinallyLabel + if (!node.finallyBlock || !(currentFlow.flags & FlowFlags.Unreachable)) { + currentFlow = finishFlowLabel(postFinallyLabel); + } } function bindSwitchStatement(node: SwitchStatement): void { diff --git a/tests/baselines/reference/unreachableFlowAfterFinally.js b/tests/baselines/reference/unreachableFlowAfterFinally.js new file mode 100644 index 00000000000..97f04b219b6 --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterFinally.js @@ -0,0 +1,27 @@ +//// [unreachableFlowAfterFinally.ts] + +function f() { + let x = 100; + try { + throw "WAT" + } + catch (e) { + + } + finally { + return x; + } +} + +//// [unreachableFlowAfterFinally.js] +function f() { + var x = 100; + try { + throw "WAT"; + } + catch (e) { + } + finally { + return x; + } +} diff --git a/tests/baselines/reference/unreachableFlowAfterFinally.symbols b/tests/baselines/reference/unreachableFlowAfterFinally.symbols new file mode 100644 index 00000000000..92a5d7b06a5 --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterFinally.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/unreachableFlowAfterFinally.ts === + +function f() { +>f : Symbol(f, Decl(unreachableFlowAfterFinally.ts, 0, 0)) + + let x = 100; +>x : Symbol(x, Decl(unreachableFlowAfterFinally.ts, 2, 7)) + + try { + throw "WAT" + } + catch (e) { +>e : Symbol(e, Decl(unreachableFlowAfterFinally.ts, 6, 11)) + + } + finally { + return x; +>x : Symbol(x, Decl(unreachableFlowAfterFinally.ts, 2, 7)) + } +} diff --git a/tests/baselines/reference/unreachableFlowAfterFinally.types b/tests/baselines/reference/unreachableFlowAfterFinally.types new file mode 100644 index 00000000000..814bebfc2fd --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterFinally.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/unreachableFlowAfterFinally.ts === + +function f() { +>f : () => number + + let x = 100; +>x : number +>100 : 100 + + try { + throw "WAT" +>"WAT" : "WAT" + } + catch (e) { +>e : any + + } + finally { + return x; +>x : number + } +} diff --git a/tests/cases/compiler/unreachableFlowAfterFinally.ts b/tests/cases/compiler/unreachableFlowAfterFinally.ts new file mode 100644 index 00000000000..4a7c0944949 --- /dev/null +++ b/tests/cases/compiler/unreachableFlowAfterFinally.ts @@ -0,0 +1,14 @@ +// @noImplicitReturns: true + +function f() { + let x = 100; + try { + throw "WAT" + } + catch (e) { + + } + finally { + return x; + } +} \ No newline at end of file