|
| 1 | +// RUN: %target-swift-emit-silgen -import-objc-header %S/Inputs/readbytes.h %s -o /dev/null -verify |
| 2 | +// |
| 3 | +// Diagnose invalid conversion from an inout argument to a raw pointer. |
| 4 | +// |
| 5 | +// These cases are caught early during Sema, so they are never seen by SILGen's implicit conversion diagnostics. |
| 6 | + |
| 7 | +func readBytes(_ pointer: UnsafeRawPointer) {} |
| 8 | +func writeBytes(_ pointer: UnsafeMutableRawPointer) {} |
| 9 | +func readInt8(_ pointer: UnsafePointer<Int8>) {} |
| 10 | +func writeInt8(_ pointer: UnsafeMutablePointer<Int8>) {} |
| 11 | +func readUInt8(_ pointer: UnsafePointer<UInt8>) {} |
| 12 | +func writeUInt8(_ pointer: UnsafeMutablePointer<UInt8>) {} |
| 13 | + |
| 14 | +// These implicit casts never worked and will continue to be unsupported. |
| 15 | +func test_unsupported<T>(arg: T) { |
| 16 | + var t: T = arg |
| 17 | + readInt8(&t) // expected-error {{cannot convert value of type 'UnsafePointer<T>' to expected argument type 'UnsafePointer<Int8>'}} |
| 18 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('T' and 'Int8') are expected to be equal}} |
| 19 | + writeInt8(&t) // expected-error {{cannot convert value of type 'UnsafeMutablePointer<T>' to expected argument type 'UnsafeMutablePointer<Int8>'}} |
| 20 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('T' and 'Int8') are expected to be equal}} |
| 21 | + readUInt8(&t) // expected-error {{cannot convert value of type 'UnsafePointer<T>' to expected argument type 'UnsafePointer<UInt8>'}} |
| 22 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('T' and 'UInt8') are expected to be equal}} |
| 23 | + writeUInt8(&t) // expected-error {{cannot convert value of type 'UnsafeMutablePointer<T>' to expected argument type 'UnsafeMutablePointer<UInt8>'}} |
| 24 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('T' and 'UInt8') are expected to be equal}} |
| 25 | + |
| 26 | + let constArray: [UInt8] = [0] |
| 27 | + readInt8(constArray) // expected-error {{cannot convert value of type 'UnsafePointer<UInt8>' to expected argument type 'UnsafePointer<Int8>'}} |
| 28 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('UInt8' and 'Int8') are expected to be equal}} |
| 29 | + |
| 30 | + // Mutating a const array obviously does not work, no need to show these |
| 31 | + // in the proposal |
| 32 | + writeBytes(constArray) // expected-error {{cannot convert value of type '[UInt8]' to expected argument type 'UnsafeMutableRawPointer'}} |
| 33 | + writeInt8(constArray) // expected-error {{cannot convert value of type '[UInt8]' to expected argument type 'UnsafeMutablePointer<Int8>'}} |
| 34 | + writeUInt8(constArray) // expected-error {{cannot convert value of type '[UInt8]' to expected argument type 'UnsafeMutablePointer<UInt8>'}} |
| 35 | + |
| 36 | + var byteArray: [UInt8] = [0] |
| 37 | + readInt8(&byteArray) // expected-error {{cannot convert value of type 'UnsafePointer<UInt8>' to expected argument type 'UnsafePointer<Int8>'}} |
| 38 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('UInt8' and 'Int8') are expected to be equal}} |
| 39 | + writeInt8(&byteArray) // expected-error {{cannot convert value of type 'UnsafeMutablePointer<UInt8>' to expected argument type 'UnsafeMutablePointer<Int8>'}} |
| 40 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('UInt8' and 'Int8') are expected to be equal}} |
| 41 | +} |
| 42 | + |
| 43 | +// These implicit casts should work according to |
| 44 | +// [SE-0324: Relax diagnostics for pointer arguments to C functions] |
| 45 | +// (https://github.com/apple/swift-evolution/blob/main/proposals/0324-c-lang-pointer-arg-conversion.md) |
| 46 | +// They currently raise a "cannot convert value" error because of |
| 47 | +// the `UInt8` vs. `Int8` mismatch. |
| 48 | +// |
| 49 | +// If we decide to support these as bug-fixes for SE-0324, then the |
| 50 | +// implicit inout-to-raw conversion should also accept them. |
| 51 | +func test_se0324_accept() { |
| 52 | + let constIntArray: [Int8] = [0] |
| 53 | + read_uchar(constIntArray) // expected-error {{cannot convert value of type 'UnsafePointer<Int8>' to expected argument type 'UnsafePointer<UInt8>'}} |
| 54 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('Int8' and 'UInt8') are expected to be equal}} |
| 55 | + |
| 56 | + let constUIntArray: [UInt8] = [0] |
| 57 | + read_char(constUIntArray) // expected-error {{cannot convert value of type 'UnsafePointer<UInt8>' to expected argument type 'UnsafePointer<CChar>' (aka 'UnsafePointer<Int8>')}} |
| 58 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('UInt8' and 'CChar' (aka 'Int8')) are expected to be equal}} |
| 59 | + |
| 60 | + var intArray: [Int8] = [0] |
| 61 | + read_uchar(intArray) // expected-error {{cannot convert value of type 'UnsafePointer<Int8>' to expected argument type 'UnsafePointer<UInt8>'}} |
| 62 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('Int8' and 'UInt8') are expected to be equal}} |
| 63 | + |
| 64 | + var uintArray: [UInt8] = [0] |
| 65 | + read_char(uintArray) // expected-error {{cannot convert value of type 'UnsafePointer<UInt8>' to expected argument type 'UnsafePointer<CChar>' (aka 'UnsafePointer<Int8>')}} |
| 66 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('UInt8' and 'CChar' (aka 'Int8')) are expected to be equal}} |
| 67 | + |
| 68 | +} |
| 69 | + |
| 70 | +// These implicit casts should work according to |
| 71 | +// SE-0324: Relax diagnostics for pointer arguments to C functions] |
| 72 | +// They currently raise a "cannot convert value" error because of |
| 73 | +// the `UInt8` vs. `Int8` mismatch. |
| 74 | +// |
| 75 | +// If we decide to support these as bug-fixes for SE-0324, then the |
| 76 | +// implicit inout-to-raw conversion should issue a warning instead. |
| 77 | +func test_se0324_error<T>(arg: T) { |
| 78 | + let constArray: [T] = [arg] |
| 79 | + read_char(constArray) // expected-error {{cannot convert value of type 'UnsafePointer<T>' to expected argument type 'UnsafePointer<CChar>' (aka 'UnsafePointer<Int8>')}} |
| 80 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('T' and 'CChar' (aka 'Int8')) are expected to be equal}} |
| 81 | + read_uchar(constArray) // expected-error {{cannot convert value of type 'UnsafePointer<T>' to expected argument type 'UnsafePointer<UInt8>'}} |
| 82 | + // expected-note@-1 {{arguments to generic parameter 'Pointee' ('T' and 'UInt8') are expected to be equal}} |
| 83 | +} |
0 commit comments