Skip to content

Commit 705a0bd

Browse files
authored
Merge pull request #15373 from eeckstein/fix-bca-4.1
BasicCalleeAnalysis: fix a problem with witness method visibility.
2 parents 04baf31 + 82743ee commit 705a0bd

File tree

2 files changed

+59
-6
lines changed

2 files changed

+59
-6
lines changed

lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,28 @@ void CalleeCache::computeWitnessMethodCalleesForWitnessTable(
142142
continue;
143143
}
144144

145-
auto Witness = WT.getConformance()->getWitness(Requirement.getDecl(),
146-
nullptr);
147-
auto DeclRef = SILDeclRef(Witness.getDecl());
148-
149-
bool canCallUnknown = !calleesAreStaticallyKnowable(M, DeclRef);
150-
145+
bool canCallUnknown = false;
146+
147+
auto Conf = WT.getConformance();
148+
switch (Conf->getProtocol()->getEffectiveAccess()) {
149+
case AccessLevel::Open:
150+
llvm_unreachable("protocols cannot have open access level");
151+
case AccessLevel::Public:
152+
canCallUnknown = true;
153+
break;
154+
case AccessLevel::Internal:
155+
if (!M.isWholeModule()) {
156+
canCallUnknown = true;
157+
break;
158+
}
159+
LLVM_FALLTHROUGH;
160+
case AccessLevel::FilePrivate:
161+
case AccessLevel::Private: {
162+
auto Witness = Conf->getWitness(Requirement.getDecl(), nullptr);
163+
auto DeclRef = SILDeclRef(Witness.getDecl());
164+
canCallUnknown = !calleesAreStaticallyKnowable(M, DeclRef);
165+
}
166+
}
151167
if (canCallUnknown)
152168
TheCallees.setInt(true);
153169
}

test/SILOptimizer/basic-callee-printer.sil

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,3 +666,40 @@ sil_vtable SomeChildItem {
666666
#SomeItem.init!initializer.1: SomeChildItem_initializer
667667
#SomeChildItem.deinit!deallocator: SomeChildItem_destructor
668668
}
669+
670+
public protocol PublicProtocol {
671+
func foo()
672+
}
673+
674+
struct SingleConformance : PublicProtocol {
675+
func foo()
676+
}
677+
678+
public func testit(p: PublicProtocol)
679+
680+
sil private [transparent] [thunk] @foo_impl : $@convention(witness_method: PublicProtocol) (@in_guaranteed SingleConformance) -> () {
681+
bb0(%0 : $*SingleConformance):
682+
%4 = tuple ()
683+
return %4 : $()
684+
}
685+
686+
// CHECK: Function call site:
687+
// CHECK: witness_method $@opened{{.*}} PublicProtocol
688+
// CHECK: apply {{.*}} PublicProtocol
689+
// CHECK-NOWMO: Incomplete callee list? : Yes
690+
// CHECK-WMO: Incomplete callee list? : Yes
691+
// CHECK: Known callees:
692+
sil @call_foo : $@convention(thin) (@in PublicProtocol) -> () {
693+
bb0(%0 : $*PublicProtocol):
694+
%5 = open_existential_addr immutable_access %0 : $*PublicProtocol to $*@opened("2226A1AC-2B95-11E8-BDF4-D0817AD3F637") PublicProtocol
695+
%6 = witness_method $@opened("2226A1AC-2B95-11E8-BDF4-D0817AD3F637") PublicProtocol, #PublicProtocol.foo!1 : <Self where Self : PublicProtocol> (Self) -> () -> (), %5 : $*@opened("2226A1AC-2B95-11E8-BDF4-D0817AD3F637") PublicProtocol : $@convention(witness_method: PublicProtocol) <τ_0_0 where τ_0_0 : PublicProtocol> (@in_guaranteed τ_0_0) -> ()
696+
%7 = apply %6<@opened("2226A1AC-2B95-11E8-BDF4-D0817AD3F637") PublicProtocol>(%5) : $@convention(witness_method: PublicProtocol) <τ_0_0 where τ_0_0 : PublicProtocol> (@in_guaranteed τ_0_0) -> ()
697+
destroy_addr %0 : $*PublicProtocol
698+
%10 = tuple ()
699+
return %10 : $()
700+
}
701+
702+
sil_witness_table hidden SingleConformance: PublicProtocol module nix {
703+
method #PublicProtocol.foo!1: <Self where Self : PublicProtocol> (Self) -> () -> () : @foo_impl
704+
}
705+

0 commit comments

Comments
 (0)