diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 076abcba81b..df794c5e708 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -506,16 +506,14 @@ namespace ts { const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && !!getImmediatelyInvokedFunctionExpression(node); // A non-async IIFE is considered part of the containing control flow. Return statements behave // similarly to break statements that exit to a label just past the statement body. - if (isIIFE) { - currentReturnTarget = createBranchLabel(); - } - else { + if (!isIIFE) { currentFlow = { flags: FlowFlags.Start }; if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) { (currentFlow).container = node; } - currentReturnTarget = node.kind === SyntaxKind.Constructor ? createBranchLabel() : undefined; } + // We create a return control flow graph for IIFEs and constructors. For constructors + // we use the return control flow graph in strict property intialization checks. currentReturnTarget = isIIFE || node.kind === SyntaxKind.Constructor ? createBranchLabel() : undefined; currentBreakTarget = undefined; currentContinueTarget = undefined; @@ -531,15 +529,14 @@ namespace ts { if (node.kind === SyntaxKind.SourceFile) { node.flags |= emitFlags; } - if (isIIFE) { + if (currentReturnTarget) { addAntecedent(currentReturnTarget, currentFlow); currentFlow = finishFlowLabel(currentReturnTarget); - } - else { if (node.kind === SyntaxKind.Constructor) { - addAntecedent(currentReturnTarget, currentFlow); (node).returnFlowNode = currentFlow; } + } + if (!isIIFE) { currentFlow = saveCurrentFlow; } currentBreakTarget = saveBreakTarget;