Skip to content

Commit 07662a1

Browse files
author
Raj Barik
committed
Fix for extensions in ProtocolConformanceAnalysis
1 parent 38aa5d3 commit 07662a1

File tree

3 files changed

+86
-1
lines changed

3 files changed

+86
-1
lines changed

lib/SILOptimizer/Analysis/ProtocolConformanceAnalysis.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/ASTContext.h"
1818
#include "swift/AST/ASTWalker.h"
1919
#include "swift/AST/Module.h"
20+
#include "swift/AST/ProtocolConformance.h"
2021
#include "swift/SIL/SILInstruction.h"
2122
#include "swift/SIL/SILModule.h"
2223
#include "swift/SIL/SILValue.h"
@@ -34,6 +35,7 @@ class NominalTypeWalker : public ASTWalker {
3435
: ProtocolConformanceCache(ProtocolConformanceCache) {}
3536

3637
bool walkToDeclPre(Decl *D) override {
38+
/// (1) Walk over all NominalTypeDecls to determine conformances.
3739
if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
3840
auto Protocols = NTD->getAllProtocols();
3941
for (auto &Protocol : Protocols) {
@@ -42,6 +44,20 @@ class NominalTypeWalker : public ASTWalker {
4244
}
4345
}
4446
}
47+
/// (2) Walk over all ExtensionDecls to determine conformances.
48+
if (auto *e = dyn_cast<ExtensionDecl>(D)) {
49+
auto *ntd = e->getExtendedNominal();
50+
if (!isa<ProtocolDecl>(ntd)) {
51+
for (auto *conformance : e->getLocalConformances()) {
52+
if (isa<NormalProtocolConformance>(conformance)) {
53+
auto *proto = conformance->getProtocol();
54+
if (proto->getEffectiveAccess() <= AccessLevel::Internal) {
55+
ProtocolConformanceCache[proto].push_back(ntd);
56+
}
57+
}
58+
}
59+
}
60+
}
4561
return true;
4662
}
4763
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -O -wmo %s -o %t/a.out
3+
// RUN: %target-codesign %t/a.out
4+
// RUN: %target-run %t/a.out | %FileCheck %s
5+
// REQUIRES: executable_test
6+
7+
protocol Foo {
8+
var myName: String { get }
9+
}
10+
11+
struct MyURL {
12+
}
13+
14+
extension MyURL : Foo {
15+
var myName : String { return "MyURL" }
16+
}
17+
18+
struct MyStruct : Foo {
19+
var myName : String { return "MyStruct" }
20+
}
21+
22+
@inline(never) func getName(_ f: Foo) -> String {
23+
return f.myName
24+
}
25+
26+
@inline(never) func getName_wrapper() {
27+
let u = MyURL()
28+
// CHECK: MyURL
29+
print(getName(u))
30+
}
31+
getName_wrapper()
32+

test/SILOptimizer/existential_transform.swift

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,42 @@ func wrap_gcp_arch<T:GP>(_ a:T,_ b:GP, _ c:inout Array<T>) -> Int {
358358
return wrap_gcp_arch(a, k, &b)
359359
}
360360

361+
protocol Foo {
362+
var myName: String { get }
363+
}
364+
365+
struct MyURL {
366+
}
367+
368+
extension MyURL : Foo {
369+
var myName : String { return "MyURL" }
370+
}
371+
372+
struct MyStruct : Foo {
373+
var myName : String { return "MyStruct" }
374+
}
375+
376+
// CHECK-LABEL: sil shared [noinline] @$s21existential_transform7getNameySSAA3Foo_pFTf4e_n : $@convention(thin) <τ_0_0 where τ_0_0 : Foo> (@in_guaranteed τ_0_0) -> @owned String {
377+
// CHECK: bb0(%0 : $*τ_0_0):
378+
// CHECK: alloc_stack
379+
// CHECK: init_existential_addr
380+
// CHECK: copy_addr
381+
// CHECK: debug_value_addr
382+
// CHECK: open_existential_addr
383+
// CHECK: witness_method
384+
// CHECK: apply
385+
// CHECK: dealloc_stack
386+
// CHECK: return
387+
// CHECK-LABEL: } // end sil function '$s21existential_transform7getNameySSAA3Foo_pFTf4e_n'
388+
@inline(never) func getName(_ f: Foo) -> String {
389+
return f.myName
390+
}
391+
392+
@inline(never) func getName_wrapper() -> Int32{
393+
let u = MyURL()
394+
return getName(u) == "MyStruct" ? 0 : 1
395+
}
396+
361397
@_optimize(none) public func foo() -> Int {
362398
cp()
363399
ncp()
@@ -371,5 +407,6 @@ struct_inout_ncp()
371407
let y:Int = gcp(GC())
372408
var a:Array<GC> = [GC()]
373409
let z:Int = gcp_arch(GC(), &a)
374-
return x + y + z
410+
let zz:Int32 = getName_wrapper()
411+
return x + y + z + Int(zz)
375412
}

0 commit comments

Comments
 (0)