Skip to content

Commit 06c6546

Browse files
committed
Don't crash if an error is emitted by Clang IR-generation.
Clang IR-generation can fail. When it does this, it destroys the module. Previously, we were blithely assuming this couldn't happen, and so we would crash on the deallocated module. Delay the finalization of the Clang code generator until our own module finalization, which is a more appropriate place for it anyway, and then just bail out of the last few steps if Clang fails.
1 parent 85cf511 commit 06c6546

File tree

6 files changed

+37
-8
lines changed

6 files changed

+37
-8
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -843,10 +843,6 @@ void IRGenModule::finishEmitAfterTopLevel() {
843843
for (auto def : Context.ExternalDefinitions) {
844844
emitExternalDefinition(def);
845845
}
846-
847-
// Let ClangCodeGen emit its global data structures (llvm.used, debug info,
848-
// etc.)
849-
finalizeClangCodeGen();
850846
}
851847

852848
static void emitLazyTypeMetadata(IRGenModule &IGM, CanType type) {

lib/IRGen/IRGen.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,8 @@ static std::unique_ptr<llvm::Module> performIRGeneration(IRGenOptions &Opts,
628628
});
629629
}
630630

631-
IGM.finalize();
631+
if (!IGM.finalize())
632+
return nullptr;
632633

633634
setModuleFlags(IGM);
634635
}
@@ -821,7 +822,9 @@ static void performParallelIRGeneration(IRGenOptions &Opts,
821822
updateLinkage(F);
822823
}
823824

824-
IGM->finalize();
825+
if (!IGM->finalize())
826+
return;
827+
825828
setModuleFlags(*IGM);
826829
}
827830

lib/IRGen/IRGenModule.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,7 @@ void IRGenModule::cleanupClangCodeGenMetadata() {
969969
(uint32_t)(swiftVersion << 8));
970970
}
971971

972-
void IRGenModule::finalize() {
972+
bool IRGenModule::finalize() {
973973
const char *ModuleHashVarName = "llvm.swift_module_hash";
974974
if (IRGen.Opts.OutputKind == IRGenOutputKind::ObjectFile &&
975975
!Module.getGlobalVariable(ModuleHashVarName)) {
@@ -1000,11 +1000,21 @@ void IRGenModule::finalize() {
10001000
addUsedGlobal(ModuleHash);
10011001
}
10021002
emitLazyPrivateDefinitions();
1003+
1004+
// Finalize clang IR-generation.
1005+
finalizeClangCodeGen();
1006+
1007+
// If that failed, report failure up and skip the final clean-up.
1008+
if (!ClangCodeGen->GetModule())
1009+
return false;
1010+
10031011
emitAutolinkInfo();
10041012
emitGlobalLists();
10051013
if (DebugInfo)
10061014
DebugInfo->finalize();
10071015
cleanupClangCodeGenMetadata();
1016+
1017+
return true;
10081018
}
10091019

10101020
/// Emit lazy definitions that have to be emitted in this specific

lib/IRGen/IRGenModule.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,12 @@ private: \
787787

788788
void emitSourceFile(SourceFile &SF, unsigned StartElem);
789789
void addLinkLibrary(const LinkLibrary &linkLib);
790-
void finalize();
790+
791+
/// Attempt to finalize the module.
792+
///
793+
/// This can fail, in which it will return false and the module will be
794+
/// invalid.
795+
bool finalize();
791796

792797
llvm::AttributeSet constructInitialAttributes();
793798

test/IRGen/Inputs/c_functions_error.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
static inline void produce_error_in_clang_irgen() {
2+
typedef double __m128d __attribute__((__vector_size__(16)));
3+
4+
__m128d a, b;
5+
__builtin_ia32_addsubps(b, a);
6+
}

test/IRGen/c_functions_error.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: not %target-swift-frontend -Xcc -mno-sse -import-objc-header %S/Inputs/c_functions_error.h -primary-file %s -emit-ir
2+
3+
// This should fail, but not crash.
4+
5+
// REQUIRES: CPU=x86_64
6+
7+
func call_buggy_builtin() {
8+
produce_error_in_clang_irgen();
9+
}

0 commit comments

Comments
 (0)