Merge pull request #11108 from jckarter/dynamic-init-breakage-4.0
[4.0] SILGen: The allocator entry point for an initializer is never `dynamic`.
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 0434306..34d526d 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -3194,7 +3194,8 @@
auto *decl = witness.getDecl();
// If the witness is dynamic, go through dynamic dispatch.
- if (decl->isDynamic())
+ if (decl->isDynamic()
+ && witness.kind != SILDeclRef::Kind::Allocator)
return WitnessDispatchKind::Dynamic;
bool isFinal = (decl->isFinal() || C->isFinal());
diff --git a/lib/SILGen/SILGenThunk.cpp b/lib/SILGen/SILGenThunk.cpp
index dd3c447..9dbe0b9 100644
--- a/lib/SILGen/SILGenThunk.cpp
+++ b/lib/SILGen/SILGenThunk.cpp
@@ -35,6 +35,8 @@
SILFunction *SILGenModule::getDynamicThunk(SILDeclRef constant,
SILConstantInfo constantInfo) {
+ assert(constant.kind != SILDeclRef::Kind::Allocator &&
+ "allocating entry point for constructor is never dynamic");
// Mangle the constant with a _TTD header.
auto name = constant.mangle(SILDeclRef::ManglingKind::DynamicThunk);
diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp
index adf6640..3310074 100644
--- a/lib/SILGen/SILGenType.cpp
+++ b/lib/SILGen/SILGenType.cpp
@@ -45,7 +45,8 @@
// If the member is dynamic, reference its dynamic dispatch thunk so that
// it will be redispatched, funneling the method call through the runtime
// hook point.
- if (derived.getDecl()->isDynamic()) {
+ if (derived.getDecl()->isDynamic()
+ && derived.kind != SILDeclRef::Kind::Allocator) {
implFn = getDynamicThunk(derived, Types.getConstantInfo(derived));
implLinkage = SILLinkage::Public;
} else {
diff --git a/test/SILGen/objc_dynamic_init.swift b/test/SILGen/objc_dynamic_init.swift
new file mode 100644
index 0000000..5ec7197
--- /dev/null
+++ b/test/SILGen/objc_dynamic_init.swift
@@ -0,0 +1,20 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen %s | %FileCheck %s
+// REQUIRES: objc_interop
+
+import Foundation
+
+protocol Person {
+ init()
+}
+
+class Driver: NSObject, Person {
+ required override init() {
+ super.init()
+ }
+}
+
+// CHECK-LABEL: sil private [transparent] [thunk] @_T{{.*}}DriverC{{.*}}CTW
+// CHECK: class_method {{%.*}} : $@thick Driver.Type, #Driver.init!allocator.1 :
+
+// CHECK-LABEL: sil_vtable Driver {
+// CHECK: #Driver.init!allocator.1: (Driver.Type) -> () -> Driver : _T{{.*}}DriverC{{.*}}C {{ *}}//