From 7b2d7124b37dfa88f78b44f5dfc9edb433992a40 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Thu, 25 Jan 2024 14:56:54 -0800 Subject: [PATCH] [SILGen] do not clear parent module when emitting stored initializer function When SILGen was emitting the stored initializer function, it updated the location to a new autogenerated location tied to the initialization expression. That in turn reset the function's parent module to null, as the initialization expression is not a decl, and thus it didn't produce a decl context SIL could use when looking for the parent module. That lead to a this function having no parent module when it was serialized, and thus a user that used this function from code in another Swift module thought that this function should use 'dllimport' on Windows, even when the parent module was built with as the static library (i.e. using the -static flag). This lead to spurious LNK4217 diagnostics when building the Swift package manager using CMake on windows. This change fixes that by preserving the parent module for such function. --- lib/SILGen/SILGen.cpp | 7 +++ ...dule_for_stored_property_initializer.swift | 55 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 test/SILGen/serialize_module_for_stored_property_initializer.swift diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index bc00be44e67..bdbd5238a41 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -967,6 +967,7 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) { auto *init = constant.getInitializationExpr(); assert(init); + auto *parentMod = f->getParentModule(); auto loc = RegularLocation::getAutoGeneratedLocation(init); preEmitFunction(constant, f, loc); PrettyStackTraceSILFunction X("silgen emitStoredPropertyInitialization", f); @@ -974,6 +975,12 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) { SILGenFunction SGF(*this, *f, initDC); SGF.emitGeneratorFunction(constant, init, /*EmitProfilerIncrement=*/true); postEmitFunction(constant, f); + // Ensure that the SIL function has a module associated with it. This + // ensures that SIL serializer serializes the module id for this function + // correctly. The parent module can be reset when the function's location is + // updated to the autogenerated location above. + if (!f->getParentModule()) + f->setParentModule(parentMod); break; } diff --git a/test/SILGen/serialize_module_for_stored_property_initializer.swift b/test/SILGen/serialize_module_for_stored_property_initializer.swift new file mode 100644 index 00000000000..9058b380a52 --- /dev/null +++ b/test/SILGen/serialize_module_for_stored_property_initializer.swift @@ -0,0 +1,55 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// RUN: %target-swift-frontend -c %t/inlinedStruct.swift -static -O -parse-as-library -module-name InlinedStructs -emit-module-path %t/InlinedStructs.swiftmodule -o %t/inlinedStruct.swift.o +// RUN: %target-swift-frontend -c -emit-ir -O %t/use.swift -I %t -o %t/use.swift.ir +// RUN: cat %t/use.swift.ir | %FileCheck %s + +// RUN: rm -rf %t/InlinedStructs.swiftmodule +// RUN: %target-swift-frontend -c %t/inlinedStruct.swift -O -parse-as-library -module-name InlinedStructs -emit-module-path %t/InlinedStructs.swiftmodule -o %t/inlinedStruct.swift.o +// RUN: %target-swift-frontend -c -emit-ir -O %t/use.swift -I %t -o %t/use.swift.ir +// RUN: cat %t/use.swift.ir | %FileCheck --check-prefix=DLLIMPORT %s + +// REQUIRES: OS=windows-msvc + +//--- inlinedStruct.swift + +@usableFromInline +struct CMSSignedData { + @usableFromInline var field: Bool? + + @inlinable + init(field: Bool?) { + self.field = field + } +} + +public struct TestS { + @usableFromInline + let x: CMSSignedData = CMSSignedData(field: false) + + @inlinable + public init() { } + + @inlinable + public var field: Bool { + return x.field! + } +} + +//--- use.swift + +import InlinedStructs + +public struct TestTwo { + let field: TestS = TestS() +} + +public func testTwo() -> Bool { + let x = TestTwo() + return x.field.field +} + +// Ensure that the variable initialization expression is not dllimported on Windows. +// CHECK: declare swiftcc i8 @"$s14InlinedStructs5TestSV1xAA13CMSSignedDataVvpfi"() +// DLLIMPORT: declare dllimport swiftcc i8 @"$s14InlinedStructs5TestSV1xAA13CMSSignedDataVvpfi"()