mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Instead of copying the data and the type and witnesses separately, use the size in the value witness table and copy everything at once. copyTypeInto assumed the type was an ordinary existential. When it was actually an extended existential, it would do an incorrect cast and read part of a pointer as the number of witness tables to copy. This would typically result in a large buffer overflow and crash. At this point we already know the type's size, so we can use that info directly rather than essentially recomputing it. rdar://163980446
89 lines
1.7 KiB
Swift
89 lines
1.7 KiB
Swift
// RUN: %target-run-simple-swift | %FileCheck %s
|
|
|
|
// UNSUPPORTED: use_os_stdlib
|
|
// UNSUPPORTED: back_deployment_runtime
|
|
// REQUIRES: OS=macosx
|
|
// REQUIRES: executable_test
|
|
|
|
protocol P1<P1T> {
|
|
associatedtype P1T
|
|
|
|
func printValue()
|
|
}
|
|
|
|
protocol P2<P2T> {
|
|
associatedtype P2T
|
|
}
|
|
|
|
protocol P3<P3T> {
|
|
associatedtype P3T
|
|
}
|
|
|
|
struct Small: P1, P2, P3 {
|
|
typealias P1T = Int
|
|
typealias P2T = Int
|
|
typealias P3T = Int
|
|
|
|
var str = "I am Small"
|
|
|
|
func printValue() { print(str) }
|
|
}
|
|
|
|
struct Big: P1, P2, P3 {
|
|
typealias P1T = Int
|
|
typealias P2T = Int
|
|
typealias P3T = Int
|
|
|
|
var str = "I am Big"
|
|
var str2 = ""
|
|
var str3 = ""
|
|
|
|
func printValue() { print(str) }
|
|
}
|
|
|
|
class Class: P1, P2, P3 {
|
|
typealias P1T = Int
|
|
typealias P2T = Int
|
|
typealias P3T = Int
|
|
|
|
var str = "I am Class"
|
|
|
|
func printValue() { print(str) }
|
|
}
|
|
|
|
func test<T>(_ value: T) {
|
|
var array: [T] = []
|
|
array.append(value)
|
|
for v in array {
|
|
(v as? P1)?.printValue()
|
|
}
|
|
}
|
|
|
|
// CHECK: I am Small
|
|
test(Small() as any P1<Int>)
|
|
// CHECK: I am Small
|
|
test(Small() as any P1<Int> & P2<Int>)
|
|
// CHECK: I am Small
|
|
test(Small() as any P1<Int> & P2<Int> & P3<Int>)
|
|
|
|
// CHECK: I am Big
|
|
test(Big() as any P1<Int>)
|
|
// CHECK: I am Big
|
|
test(Big() as any P1<Int> & P2<Int>)
|
|
// CHECK: I am Big
|
|
test(Big() as any P1<Int> & P2<Int> & P3<Int>)
|
|
|
|
// CHECK: I am Class
|
|
test(Class() as any P1<Int>)
|
|
// CHECK: I am Class
|
|
test(Class() as any P1<Int> & P2<Int>)
|
|
// CHECK: I am Class
|
|
test(Class() as any P1<Int> & P2<Int> & P3<Int>)
|
|
|
|
// CHECK: I am Class
|
|
test(Class() as any AnyObject & P1<Int>)
|
|
// CHECK: I am Class
|
|
test(Class() as any AnyObject & P1<Int> & P2<Int>)
|
|
// CHECK: I am Class
|
|
test(Class() as any AnyObject & P1<Int> & P2<Int> & P3<Int>)
|