Skip to content

Commit 528e66d

Browse files
committed
[IRGen] Make sure a C++ constructor thunk is called when it's needed (#71790)
This fixes a bug where the thunk for a C++ constructor call wasn't being called when the constructor was called the second time. Cherrypick commit 97a8148 Cherrypick PR #71790
1 parent f55f713 commit 528e66d

File tree

3 files changed

+19
-8
lines changed

3 files changed

+19
-8
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3332,6 +3332,10 @@ llvm::Constant *swift::irgen::emitCXXConstructorThunkIfNeeded(
33323332
return ctorAddress;
33333333
}
33343334

3335+
// Check whether we've created the thunk already.
3336+
if (auto *thunkFn = IGM.Module.getFunction(name))
3337+
return thunkFn;
3338+
33353339
llvm::Function *thunk = llvm::Function::Create(
33363340
assumedFnType, llvm::Function::PrivateLinkage, name, &IGM.Module);
33373341

@@ -3412,10 +3416,15 @@ llvm::Function *IRGenModule::getAddrOfSILFunction(
34123416
LinkEntity entity =
34133417
LinkEntity::forSILFunction(f, shouldCallPreviousImplementation);
34143418

3415-
// Check whether we've created the function already.
3419+
auto clangDecl = f->getClangDecl();
3420+
auto cxxCtor = dyn_cast_or_null<clang::CXXConstructorDecl>(clangDecl);
3421+
3422+
// Check whether we've created the function already. If the function is a C++
3423+
// constructor, don't return the constructor here as a thunk might be needed
3424+
// to call the constructor.
34163425
// FIXME: We should integrate this into the LinkEntity cache more cleanly.
34173426
llvm::Function *fn = Module.getFunction(entity.mangleAsString());
3418-
if (fn) {
3427+
if (fn && !cxxCtor) {
34193428
if (forDefinition) {
34203429
updateLinkageForDefinition(*this, fn, entity);
34213430
}
@@ -3427,7 +3436,7 @@ llvm::Function *IRGenModule::getAddrOfSILFunction(
34273436
// the insert-before point.
34283437
llvm::Constant *clangAddr = nullptr;
34293438
bool isObjCDirect = false;
3430-
if (auto clangDecl = f->getClangDecl()) {
3439+
if (clangDecl) {
34313440
// If we have an Objective-C Clang declaration, it must be a direct
34323441
// method and we want to generate the IR declaration ourselves.
34333442
if (auto objcDecl = dyn_cast<clang::ObjCMethodDecl>(clangDecl)) {
@@ -3438,7 +3447,7 @@ llvm::Function *IRGenModule::getAddrOfSILFunction(
34383447
clangAddr = getAddrOfClangGlobalDecl(globalDecl, forDefinition);
34393448
}
34403449

3441-
if (auto ctor = dyn_cast<clang::CXXConstructorDecl>(clangDecl)) {
3450+
if (cxxCtor) {
34423451
Signature signature = getSignature(f->getLoweredFunctionType());
34433452

34443453
// The thunk has private linkage, so it doesn't need to have a predictable
@@ -3448,7 +3457,7 @@ llvm::Function *IRGenModule::getAddrOfSILFunction(
34483457
stream << "__swift_cxx_ctor";
34493458
entity.mangle(stream);
34503459

3451-
clangAddr = emitCXXConstructorThunkIfNeeded(*this, signature, ctor, name,
3460+
clangAddr = emitCXXConstructorThunkIfNeeded(*this, signature, cxxCtor, name,
34523461
clangAddr);
34533462
}
34543463
}

test/Interop/Cxx/class/constructors-irgen-windows.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ import Constructors
99
import TypeClassification
1010

1111
public func createHasVirtualBase() -> HasVirtualBase {
12-
// MICROSOFT_X64: define dllexport swiftcc void @"$s7MySwift20createHasVirtualBaseSo0{{bcD0VyF|deF0VyF}}"(ptr noalias sret({{.*}}) %0)
12+
// MICROSOFT_X64: define dllexport swiftcc void @"$s7MySwift20createHasVirtualBaseSo0{{bcD0VyF|deF0VyF}}"(ptr noalias sret({{.*}}) [[V0:%.*]])
1313
// MICROSOFT_X64-NOT: define
1414
// Note `this` return type and implicit "most derived" argument.
15-
// MICROSOFT_X64: call ptr @"??0HasVirtualBase@@QEAA@UArgType@@@Z"(ptr %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 1)
15+
// MICROSOFT_X64: [[V1:%.*]] = alloca %{{.*}}, align 8
16+
// MICROSOFT_X64: call ptr @"??0HasVirtualBase@@QEAA@UArgType@@@Z"(ptr [[V1]], i32 %{{[0-9]+}}, i32 1)
17+
// MICROSOFT_X64: call ptr @"??0HasVirtualBase@@QEAA@UArgType@@@Z"(ptr [[V0]], i32 %{{[0-9]+}}, i32 1)
18+
let _ : HasVirtualBase = HasVirtualBase(ArgType())
1619
return HasVirtualBase(ArgType())
1720
}
1821

test/Interop/Cxx/value-witness-table/custom-destructors-virtual.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -enable-experimental-cxx-interop -Xcc -fno-rtti -O)
77
//
88
// REQUIRES: executable_test
9-
// XFAIL: OS=windows-msvc
109

1110
import CustomDestructor
1211
import StdlibUnittest

0 commit comments

Comments
 (0)