Skip to content

Commit

Permalink
Fix a bug where a constructor call of an open class is devirtualized …
Browse files Browse the repository at this point in the history
…although the call should be done dynamically.

fixes rdar://problem/28882879
  • Loading branch information
eeckstein committed Oct 21, 2016
1 parent b527e0d commit 35916a2
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
8 changes: 6 additions & 2 deletions lib/SILOptimizer/Utils/Local.cpp
Expand Up @@ -2719,8 +2719,12 @@ bool swift::calleesAreStaticallyKnowable(SILModule &M, SILDeclRef Decl) {
case Accessibility::Open:
return false;
case Accessibility::Public:
if (auto ctor = dyn_cast<ConstructorDecl>(AFD)) {
if (ctor->isRequired())
if (isa<ConstructorDecl>(AFD)) {
// Constructors are special: a derived class in another module can
// "override" a constructor if its class is "open", although the
// constructor itself is not open.
auto *ND = AFD->getExtensionType()->getNominalOrBoundGenericNominal();
if (ND->getEffectiveAccess() == Accessibility::Open)
return false;
}
SWIFT_FALLTHROUGH;
Expand Down
32 changes: 32 additions & 0 deletions test/SILOptimizer/mandatory_inlining_devirt.swift
@@ -0,0 +1,32 @@
// RUN: %target-swift-frontend %s -module-name test -emit-sil -o - -verify | %FileCheck %s


// Constructor calls are dispatched dynamically for open classes, even if
// the constructor itself is not "open".

open class OpenClass {
// CHECK-LABEL: sil @_TFC4test9OpenClasscfT1xSi_S0_ : $@convention(method) (Int, @owned OpenClass) -> @owned OpenClass
// CHECK: [[M:%[0-9]+]] = class_method %1 : $OpenClass, #OpenClass.init!initializer.1 : (OpenClass.Type) -> (Int, Int) -> OpenClass
// CHECK: apply [[M]]
// CHECK: return
public convenience init(x: Int) {
self.init(x: x, y: 27)
}
public init(x: Int, y: Int) {
}
}

// Static dispatch for not-open class (we are compiling with -wmo).

public class PublicClass {
// CHECK-LABEL: sil @_TFC4test11PublicClasscfT1xSi_S0_ : $@convention(method) (Int, @owned PublicClass) -> @owned PublicClass
// CHECK: [[M:%[0-9]+]] = function_ref @_TFC4test11PublicClasscfT1xSi1ySi_S0_ : $@convention(method) (Int, Int, @owned PublicClass) -> @owned PublicClass
// CHECK: apply [[M]]
// CHECK: return
public convenience init(x: Int) {
self.init(x: x, y: 27)
}
public init(x: Int, y: Int) {
}
}

0 comments on commit 35916a2

Please sign in to comment.