File: devirt_concrete_subclass_of_generic_class.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (139 lines) | stat: -rw-r--r-- 3,552 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// RUN: %target-swift-frontend -emit-sil -O %s | %FileCheck %s

// Check that devirtualizer can properly handle concrete non-generic subclasses 
// of generic classes.
// It should not crash on them.

public class Base<T> {
   func foo() -> Int32 {
     return 1
   }
   
   func boo() -> Int32 {
     return 11
   }
}

public class Derived: Base<Int> {
   override func foo() -> Int32 {
     return 2
   }
}

// CHECK-LABEL: sil [noinline] @$s41devirt_concrete_subclass_of_generic_class5test1s5Int32VyF
@inline(never)
public func test1() -> Int32 {
  let o = Derived()
  return o.foo() + o.boo()
}

@inline(never)
public func test2(_ o: Derived) -> Int32 {
  return o.foo() + o.boo()
}


@inline(never)
public func test3() -> Int32 {
  let o: Base<Int> = Derived()
  return o.foo() + o.boo()
}

@inline(never)
public func test4(_ o: Base<Int>) -> Int32 {
  return o.foo() + o.boo()
}

@inline(never)
public func test5<T>(_ o: Base<T>) -> Int32 {
  return o.foo() + o.boo()
}

print(test1())
print(test2(Derived()))

print(test3())
print(test4(Derived()))

print(test5(Derived()))

// Check that we handle indirect devirtualization through an intermediate
// method. rdar://problem/24993618

private class IndirectMethodCall<T> {
    func bug() {
        overrideMe()
    }
    
    @inline(never)
    func overrideMe() { }
}

private class IndirectChildConcrete: IndirectMethodCall<Int> {
    @inline(never)
    override func overrideMe() { }
}

private class IndirectChildTuple<U>: IndirectMethodCall<(U, U)> {
    @inline(never)
    override func overrideMe() { }
}

private class IndirectChildTupleConcrete: IndirectChildTuple<Int> {
    @inline(never)
    override func overrideMe() { }
}

private class IndirectChildMeta<U>: IndirectMethodCall<U.Type> {
    @inline(never)
    override func overrideMe() { }
}
private class IndirectChildMetaConcrete: IndirectChildMeta<Int> {
    @inline(never)
    override func overrideMe() { }
}

private class IndirectChildBoundGeneric<U>: IndirectMethodCall<Array<U>> {
    @inline(never)
    override func overrideMe() { }
}

private class IndirectChildBoundGenericConcrete:
      IndirectChildBoundGeneric<Int> {
    @inline(never)
    override func overrideMe() { }
}

private class IndirectChildFunction<U>: IndirectMethodCall<(U) -> U> {
    @inline(never)
    override func overrideMe() { }
}
private class IndirectChildFunctionConcrete: IndirectChildFunction<Int> {
    @inline(never)
    override func overrideMe() { }
}

// CHECK-LABEL: sil {{.*}} @{{.*}}test6
@inline(never)
func test6() {
  // CHECK: function_ref @{{.*}}IndirectChildConcrete{{.*}}overrideMe
  IndirectChildConcrete().bug()
  // CHECK: function_ref @{{.*}}IndirectChildTuple{{.*}}overrideMe
  IndirectChildTuple<Int>().bug()
  // CHECK: function_ref @{{.*}}IndirectChildTupleConcrete{{.*}}overrideMe
  IndirectChildTupleConcrete().bug()
  // CHECK: function_ref @{{.*}}IndirectChildMeta{{.*}}overrideMe
  IndirectChildMeta<Int>().bug()
  // CHECK: function_ref @{{.*}}IndirectChildMetaConcrete{{.*}}overrideMe
  IndirectChildMetaConcrete().bug()
  // CHECK: function_ref @{{.*}}IndirectChildBoundGeneric{{.*}}overrideMe
  IndirectChildBoundGeneric<Int>().bug()
  // CHECK: function_ref @{{.*}}IndirectChildBoundGenericConcrete{{.*}}overrideMe
  IndirectChildBoundGenericConcrete().bug()
  // CHECK: function_ref @{{.*}}IndirectChildFunction{{.*}}overrideMe
  IndirectChildFunction<Int>().bug()
  // CHECK: function_ref @{{.*}}IndirectChildFunctionConcrete{{.*}}overrideMe
  IndirectChildFunctionConcrete().bug()
}

print(test6())