From 1b8243daba4c94290ac45a849e34286827dc3b05 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 24 Dec 2020 21:24:43 +0200 Subject: [PATCH] fix(42088): fix crash on unreachability condition in for statement --- src/compiler/checker.ts | 6 ++++- .../reference/reachabilityChecks8.errors.txt | 17 +++++++++++++ .../reference/reachabilityChecks8.js | 15 +++++++++++ .../reference/reachabilityChecks8.symbols | 10 ++++++++ .../reference/reachabilityChecks8.types | 25 +++++++++++++++++++ tests/cases/compiler/reachabilityChecks8.ts | 9 +++++++ 6 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/reachabilityChecks8.errors.txt create mode 100644 tests/baselines/reference/reachabilityChecks8.js create mode 100644 tests/baselines/reference/reachabilityChecks8.symbols create mode 100644 tests/baselines/reference/reachabilityChecks8.types create mode 100644 tests/cases/compiler/reachabilityChecks8.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1c3bc622b0c75..66c3817196d0e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21769,8 +21769,12 @@ namespace ts { return some((flow).antecedents, f => isReachableFlowNodeWorker(f, /*noCacheCheck*/ false)); } else if (flags & FlowFlags.LoopLabel) { + const antecedents = (flow).antecedents; + if (antecedents === undefined || antecedents.length === 0) { + return false; + } // A loop is reachable if the control flow path that leads to the top is reachable. - flow = (flow).antecedents![0]; + flow = antecedents[0]; } else if (flags & FlowFlags.SwitchClause) { // The control flow path representing an unmatched value in a switch statement with diff --git a/tests/baselines/reference/reachabilityChecks8.errors.txt b/tests/baselines/reference/reachabilityChecks8.errors.txt new file mode 100644 index 0000000000000..839c650d1142d --- /dev/null +++ b/tests/baselines/reference/reachabilityChecks8.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/reachabilityChecks8.ts(4,24): error TS7027: Unreachable code detected. +tests/cases/compiler/reachabilityChecks8.ts(5,24): error TS7027: Unreachable code detected. + + +==== tests/cases/compiler/reachabilityChecks8.ts (2 errors) ==== + try { + for ( + (function () { throw "1"; })(); + (function () { throw "2"; })(); + ~~~~~~~~~~ +!!! error TS7027: Unreachable code detected. + (function () { throw "3"; })() + ~~~~~~~~~~ +!!! error TS7027: Unreachable code detected. + ) {} + } catch (e) {} + \ No newline at end of file diff --git a/tests/baselines/reference/reachabilityChecks8.js b/tests/baselines/reference/reachabilityChecks8.js new file mode 100644 index 0000000000000..fe33f8fe2b446 --- /dev/null +++ b/tests/baselines/reference/reachabilityChecks8.js @@ -0,0 +1,15 @@ +//// [reachabilityChecks8.ts] +try { + for ( + (function () { throw "1"; })(); + (function () { throw "2"; })(); + (function () { throw "3"; })() + ) {} +} catch (e) {} + + +//// [reachabilityChecks8.js] +try { + for ((function () { throw "1"; })(); (function () { throw "2"; })(); (function () { throw "3"; })()) { } +} +catch (e) { } diff --git a/tests/baselines/reference/reachabilityChecks8.symbols b/tests/baselines/reference/reachabilityChecks8.symbols new file mode 100644 index 0000000000000..9e95d0979207e --- /dev/null +++ b/tests/baselines/reference/reachabilityChecks8.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/reachabilityChecks8.ts === +try { + for ( + (function () { throw "1"; })(); + (function () { throw "2"; })(); + (function () { throw "3"; })() + ) {} +} catch (e) {} +>e : Symbol(e, Decl(reachabilityChecks8.ts, 6, 9)) + diff --git a/tests/baselines/reference/reachabilityChecks8.types b/tests/baselines/reference/reachabilityChecks8.types new file mode 100644 index 0000000000000..0e595a2404cb3 --- /dev/null +++ b/tests/baselines/reference/reachabilityChecks8.types @@ -0,0 +1,25 @@ +=== tests/cases/compiler/reachabilityChecks8.ts === +try { + for ( + (function () { throw "1"; })(); +>(function () { throw "1"; })() : never +>(function () { throw "1"; }) : () => never +>function () { throw "1"; } : () => never +>"1" : "1" + + (function () { throw "2"; })(); +>(function () { throw "2"; })() : never +>(function () { throw "2"; }) : () => never +>function () { throw "2"; } : () => never +>"2" : "2" + + (function () { throw "3"; })() +>(function () { throw "3"; })() : never +>(function () { throw "3"; }) : () => never +>function () { throw "3"; } : () => never +>"3" : "3" + + ) {} +} catch (e) {} +>e : any + diff --git a/tests/cases/compiler/reachabilityChecks8.ts b/tests/cases/compiler/reachabilityChecks8.ts new file mode 100644 index 0000000000000..5f59df0f17d5f --- /dev/null +++ b/tests/cases/compiler/reachabilityChecks8.ts @@ -0,0 +1,9 @@ +// @allowUnreachableCode: false + +try { + for ( + (function () { throw "1"; })(); + (function () { throw "2"; })(); + (function () { throw "3"; })() + ) {} +} catch (e) {}