[Dependency Scanner] Speculatively fix diagnostic consumer use-after-destroy in compiler sub-instances

In `runInSubCompilerInstance`, the `CompilerInstance` was declared before its diagnostic consumers (`ForwardingDiagnosticConsumer` and `NullDiagnosticConsumer`). C++ destroys local variables in reverse declaration order, so the consumers were destroyed before `~CompilerInstance` ran. During `ASTContext` cleanup, any code emitting diagnostics would access the already-destroyed consumers via dangling pointers in the `DiagnosticEngine`, possibly causing undefined behavior that may manifest as heap corruption and a crash.

Fix by declaring the diagnostic consumers before the CompilerInstance so they outlive it.

Resolves rdar://172440435.
This commit is contained in:
Artem Chikin
2026-03-16 15:15:02 +00:00
parent d13cbbfd33
commit fd992cc836
+3 -1
View File
@@ -2151,9 +2151,11 @@ InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleName,
subInvocation.getFrontendOptions().InputsAndOutputs
.setMainAndSupplementaryOutputs(outputFiles, ModuleOutputPaths);
CompilerInstance subInstance;
// Diagnostic consumers must outlive subInstance, since subInstance's
// DiagnosticEngine holds raw pointers to them.
ForwardingDiagnosticConsumer FDC(*Diags);
NullDiagnosticConsumer noopConsumer;
CompilerInstance subInstance;
if (!silenceErrors) {
subInstance.addDiagnosticConsumer(&FDC);
} else {