Skip to content

Commit b0bb723

Browse files
committed
[Frontend] Handle errors from performEndOfPipelineActions
The use of `SWIFT_DEFER` previously meant that we may return `false` from `performCompile` even if an error was produced from `performEndOfPipelineActions`. To remedy this, introduce a lambda that both calls `performEndOfPipelineActions`, and checks to see if there was an error. Then, enforce that all exit paths call this lambda.
1 parent 63c8044 commit b0bb723

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

lib/FrontendTool/FrontendTool.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,11 +1315,20 @@ static bool performCompile(CompilerInstance &Instance,
13151315
return true;
13161316
}
13171317

1318+
bool didFinishPipeline = false;
13181319
SWIFT_DEFER {
1320+
assert(didFinishPipeline && "Returned without calling finishPipeline");
1321+
};
1322+
1323+
auto finishPipeline = [&](bool hadError) -> bool {
13191324
// We might have freed the ASTContext already, but in that case we would
13201325
// have already performed these actions.
1321-
if (Instance.hasASTContext())
1326+
if (Instance.hasASTContext()) {
13221327
performEndOfPipelineActions(Instance);
1328+
hadError |= Instance.getASTContext().hadError();
1329+
}
1330+
didFinishPipeline = true;
1331+
return hadError;
13231332
};
13241333

13251334
auto &Context = Instance.getASTContext();
@@ -1334,7 +1343,7 @@ static bool performCompile(CompilerInstance &Instance,
13341343
(void)kind;
13351344
} else if (Action == FrontendOptions::ActionType::ResolveImports) {
13361345
Instance.performParseAndResolveImportsOnly();
1337-
return Context.hadError();
1346+
return finishPipeline(Context.hadError());
13381347
} else {
13391348
Instance.performSema();
13401349
}
@@ -1346,11 +1355,11 @@ static bool performCompile(CompilerInstance &Instance,
13461355
if (auto *SF = dyn_cast<SourceFile>(file))
13471356
(void)SF->getTopLevelDecls();
13481357
}
1349-
return Context.hadError();
1358+
return finishPipeline(Context.hadError());
13501359
}
13511360

13521361
if (Action == FrontendOptions::ActionType::ScanDependencies)
1353-
return scanDependencies(Instance);
1362+
return finishPipeline(scanDependencies(Instance));
13541363

13551364
if (observer)
13561365
observer->performedSemanticAnalysis(Instance);
@@ -1371,19 +1380,20 @@ static bool performCompile(CompilerInstance &Instance,
13711380
}
13721381

13731382
if (auto r = dumpASTIfNeeded(Instance))
1374-
return *r;
1383+
return finishPipeline(*r);
13751384

13761385
if (Context.hadError())
1377-
return true;
1386+
return finishPipeline(/*hadError*/ true);
13781387

13791388
// We've just been told to perform a typecheck, so we can return now.
13801389
if (Action == FrontendOptions::ActionType::Typecheck)
1381-
return false;
1390+
return finishPipeline(/*hadError*/ false);
13821391

13831392
assert(FrontendOptions::doesActionGenerateSIL(Action) &&
13841393
"All actions not requiring SILGen must have been handled!");
13851394

1386-
return performCompileStepsPostSema(Instance, ReturnValue, observer);
1395+
return finishPipeline(
1396+
performCompileStepsPostSema(Instance, ReturnValue, observer));
13871397
}
13881398

13891399
static bool serializeSIB(SILModule *SM, const PrimarySpecificPaths &PSPs,

0 commit comments

Comments
 (0)