mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
- Don't attempt to insert fixes if there are restrictions present, they'd inform the failures. Inserting fixes too early doesn't help the solver because restriction matching logic would record the same fixes. - Adjust impact of the fixes. Optional conversions shouldn't impact the score in any way because they are not the source of the issue. - Look through one level of optional when failure is related to optional injection. The diagnostic is going to be about underlying type, so there is no reason to print optional on right-hand side.
333 lines
13 KiB
Swift
333 lines
13 KiB
Swift
// RUN: %empty-directory(%t)
|
|
|
|
// RUN: %gyb %s -o %t/swift_to_c_pointer_conversions.swift
|
|
|
|
// RUN: %line-directive %t/swift_to_c_pointer_conversions.swift -- %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -import-objc-header %S/Inputs/c_pointer_conversions.h %t/swift_to_c_pointer_conversions.swift -typecheck -verify
|
|
|
|
// REQUIRES: objc_interop
|
|
|
|
func test_raw_ptr(ptr: UnsafeRawPointer) {
|
|
char_ptr_func(ptr) // expected-error {{}}
|
|
unsigned_char_ptr_func(ptr) // expected-error {{}}
|
|
|
|
const_char_ptr_func(ptr) // Ok
|
|
const_unsigned_char_ptr_func(ptr) // Ok
|
|
|
|
% for Size in ['16', '32', '64']:
|
|
int_${Size}_ptr_func(ptr) // expected-error {{}}
|
|
uint_${Size}_ptr_func(ptr) // expected-error {{}}
|
|
|
|
const_int_${Size}_ptr_func(ptr) // expected-error {{}}
|
|
const_uint_${Size}_ptr_func(ptr) // expected-error {{}}
|
|
% end
|
|
}
|
|
|
|
func test_mutable_raw_pointer(ptr: UnsafeMutableRawPointer) {
|
|
char_ptr_func(ptr) // Ok
|
|
unsigned_char_ptr_func(ptr) // Ok
|
|
|
|
const_char_ptr_func(ptr) // Ok
|
|
const_unsigned_char_ptr_func(ptr) // Ok
|
|
|
|
% for Size in ['16', '32', '64']:
|
|
int_${Size}_ptr_func(ptr) // expected-error {{}}
|
|
uint_${Size}_ptr_func(ptr) // expected-error {{}}
|
|
|
|
const_int_${Size}_ptr_func(ptr) // expected-error {{}}
|
|
const_uint_${Size}_ptr_func(ptr) // expected-error {{}}
|
|
% end
|
|
}
|
|
|
|
%for TestPtrSize in ['8', '16', '32', '64']:
|
|
// Immutable pointers can be converted only to their immutable (regardless of sign) counterparts.
|
|
func test_${TestPtrSize}_bit_ptrs(sptr: UnsafePointer<Int${TestPtrSize}>,
|
|
uptr: UnsafePointer<UInt${TestPtrSize}>,
|
|
osptr: UnsafePointer<Int${TestPtrSize}>?,
|
|
ouptr: UnsafePointer<UInt${TestPtrSize}>?) {
|
|
% for pointer in ['sptr', 'uptr']:
|
|
char_ptr_func(${pointer}) // expected-error {{}}
|
|
opt_char_ptr_func(${pointer}) // expected-error {{}}
|
|
|
|
const_char_ptr_func(${pointer}) // Ok
|
|
const_opt_char_ptr_func(${pointer}) // Ok
|
|
|
|
unsigned_char_ptr_func(${pointer}) // expected-error {{}}
|
|
unsigned_opt_char_ptr_func(${pointer}) // expected-error {{}}
|
|
|
|
const_unsigned_char_ptr_func(${pointer}) // Ok
|
|
const_opt_unsigned_char_ptr_func(${pointer}) // Ok
|
|
% end
|
|
|
|
% for pointer in ['osptr', 'ouptr']:
|
|
opt_char_ptr_func(${pointer}) // expected-error {{}}
|
|
const_opt_char_ptr_func(${pointer}) // Ok
|
|
unsigned_opt_char_ptr_func(${pointer}) // expected-error {{}}
|
|
const_opt_unsigned_char_ptr_func(${pointer}) // Ok
|
|
% end
|
|
|
|
% for pointer in ['sptr', 'uptr']:
|
|
% for Size in ['16', '32', '64']:
|
|
|
|
% if Size == TestPtrSize:
|
|
int_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
|
|
uint_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
|
|
opt_int_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
|
|
opt_uint_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
|
|
|
|
const_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
const_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
const_opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
const_opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
% else:
|
|
int_${Size}_ptr_func(${pointer}) // expected-error {{}}
|
|
uint_${Size}_ptr_func(${pointer}) // expected-error {{}}
|
|
opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}}
|
|
opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}}
|
|
|
|
const_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
const_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
const_opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
const_opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
% end
|
|
% end
|
|
% end
|
|
|
|
|
|
% for pointer in ['osptr', 'ouptr']:
|
|
% for Size in ['16', '32', '64']:
|
|
% if Size == TestPtrSize:
|
|
opt_int_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
|
|
opt_uint_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
|
|
const_opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
const_opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
% else:
|
|
opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}}
|
|
opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}}
|
|
const_opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
const_opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
% end
|
|
% end
|
|
% end
|
|
}
|
|
|
|
% end
|
|
|
|
%for TestPtrSize in ['8', '16', '32', '64']:
|
|
// Mutable pointers can be converted to both immutable and mutable pointers when
|
|
// passed to C/ObjC imported functions.
|
|
func test_mutable_${TestPtrSize}_bit_ptrs(sptr: UnsafeMutablePointer<Int${TestPtrSize}>,
|
|
uptr: UnsafeMutablePointer<UInt${TestPtrSize}>,
|
|
osptr: UnsafeMutablePointer<Int${TestPtrSize}>?,
|
|
ouptr: UnsafeMutablePointer<UInt${TestPtrSize}>?) {
|
|
% for pointer in ['sptr', 'uptr']:
|
|
char_ptr_func(${pointer}) // Ok
|
|
opt_char_ptr_func(${pointer}) // Ok
|
|
|
|
const_char_ptr_func(${pointer}) // Ok
|
|
const_opt_char_ptr_func(${pointer}) // Ok
|
|
|
|
unsigned_char_ptr_func(${pointer}) // Ok
|
|
opt_unsigned_char_ptr_func(${pointer}) // Ok
|
|
|
|
const_unsigned_char_ptr_func(${pointer}) // Ok
|
|
const_opt_unsigned_char_ptr_func(${pointer}) // Ok
|
|
% end
|
|
|
|
% for pointer in ['osptr', 'ouptr']:
|
|
opt_char_ptr_func(${pointer}) // Ok
|
|
const_opt_char_ptr_func(${pointer}) // Ok
|
|
opt_unsigned_char_ptr_func(${pointer}) // Ok
|
|
const_opt_unsigned_char_ptr_func(${pointer}) // Ok
|
|
% end
|
|
|
|
% for pointer in ['sptr', 'uptr']:
|
|
% for Size in ['16', '32', '64']:
|
|
|
|
% if Size == TestPtrSize:
|
|
int_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
|
|
const_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
const_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
const_opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
const_opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
% else:
|
|
int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
|
|
const_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
const_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
const_opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
const_opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
% end
|
|
% end
|
|
% end
|
|
|
|
% for pointer in ['osptr', 'ouptr']:
|
|
% for Size in ['16', '32', '64']:
|
|
% if Size == TestPtrSize:
|
|
opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
const_opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
const_opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
|
|
% else:
|
|
opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
const_opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
const_opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
|
|
% end
|
|
% end
|
|
% end
|
|
}
|
|
|
|
% end
|
|
|
|
func test_raw_ptr_value_to_optional_promotion(
|
|
riptr: UnsafeRawPointer,
|
|
rmptr: UnsafeMutableRawPointer) {
|
|
opt_char_ptr_func(riptr) // expected-error {{}}
|
|
const_opt_char_ptr_func(riptr) // Ok
|
|
|
|
opt_char_ptr_func(rmptr) // Ok
|
|
const_opt_char_ptr_func(rmptr) // Ok
|
|
|
|
opt_unsigned_char_ptr_func(riptr) // expected-error {{}}
|
|
const_opt_unsigned_char_ptr_func(riptr) // Ok
|
|
|
|
opt_unsigned_char_ptr_func(rmptr) // Ok
|
|
const_opt_unsigned_char_ptr_func(rmptr) // Ok
|
|
|
|
% for Ptr in ['riptr', 'rmptr']:
|
|
% for Size in ['16', '32', '64']:
|
|
opt_int_${Size}_ptr_func(${Ptr}) // expected-error {{}}
|
|
opt_uint_${Size}_ptr_func(${Ptr}) // expected-error {{}}
|
|
|
|
const_opt_int_${Size}_ptr_func(${Ptr}) // expected-error {{}}
|
|
const_opt_uint_${Size}_ptr_func(${Ptr}) // expected-error {{}}
|
|
% end
|
|
% end
|
|
}
|
|
|
|
func test_raw_ptr_optional_to_optional_conversion(
|
|
riptr: UnsafeRawPointer?,
|
|
rmptr: UnsafeMutableRawPointer?) {
|
|
opt_char_ptr_func(riptr) // expected-error {{}}
|
|
const_opt_char_ptr_func(riptr) // Ok
|
|
|
|
opt_char_ptr_func(rmptr) // Ok
|
|
const_opt_char_ptr_func(rmptr) // Ok
|
|
|
|
opt_unsigned_char_ptr_func(rmptr) // Ok
|
|
const_opt_unsigned_char_ptr_func(rmptr) // Ok
|
|
|
|
% for Ptr in ['riptr', 'rmptr']:
|
|
% for Size in ['16', '32', '64']:
|
|
opt_int_${Size}_ptr_func(${Ptr}) // expected-error {{}}
|
|
opt_uint_${Size}_ptr_func(${Ptr}) // expected-error {{}}
|
|
|
|
const_opt_int_${Size}_ptr_func(${Ptr}) // expected-error {{}}
|
|
const_opt_uint_${Size}_ptr_func(${Ptr}) // expected-error {{}}
|
|
% end
|
|
% end
|
|
}
|
|
|
|
// Check that implicit conversions don't make expressions ambiguous
|
|
func test_overloaded_ref_is_not_ambiguous() {
|
|
func overloaded_func() -> UnsafeRawPointer { fatalError() }
|
|
func overloaded_func() -> UnsafePointer<Int8> { fatalError() }
|
|
|
|
const_char_ptr_func(overloaded_func()) // Ok
|
|
const_opt_char_ptr_func(overloaded_func()) // Ok
|
|
}
|
|
|
|
func test_tailored_diagnostic(ptr: UnsafeRawPointer, tptr: UnsafePointer<Int8>) {
|
|
func swift_uint8_func(_: UnsafePointer<UInt8>) {}
|
|
func swift_int8_func(_: UnsafePointer<Int8>) {}
|
|
func opt_arg_func(_: UnsafePointer<Int8>?) {}
|
|
|
|
swift_uint8_func(ptr)
|
|
// expected-error@-1 {{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'UnsafePointer<UInt8>' because local function 'swift_uint8_func' was not imported from C header}}
|
|
swift_uint8_func(tptr)
|
|
// expected-error@-1 {{cannot convert value of type 'UnsafePointer<Int8>' to expected argument type 'UnsafePointer<UInt8>' because local function 'swift_uint8_func' was not imported from C header}}
|
|
|
|
swift_int8_func(ptr)
|
|
// expected-error@-1 {{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'UnsafePointer<Int8>' because local function 'swift_int8_func' was not imported from C header}}
|
|
swift_int8_func(tptr) // Ok
|
|
|
|
opt_arg_func(ptr)
|
|
// expected-error@-1 {{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'UnsafePointer<Int8>?' because local function 'opt_arg_func' was not imported from C header}}
|
|
opt_arg_func(tptr) // Ok
|
|
|
|
let optrS8: UnsafePointer<Int8>? = nil
|
|
let optrU8: UnsafePointer<UInt8>? = nil
|
|
|
|
opt_arg_func(optrS8) // Ok
|
|
opt_arg_func(optrU8)
|
|
// expected-error@-1 {{cannot convert value of type 'UnsafePointer<UInt8>?' to expected argument type 'UnsafePointer<Int8>?' because local function 'opt_arg_func' was not imported from C header}}
|
|
}
|
|
|
|
func test_inout_to_pointer_conversion() {
|
|
% for Size in ['16', '32', '64']:
|
|
var x${Size}: Int${Size} = 0
|
|
|
|
void_ptr_func(&x${Size}) // Ok
|
|
const_void_ptr_func(&x${Size}) // Ok
|
|
opt_void_ptr_func(&x${Size}) // Ok
|
|
|
|
char_ptr_func(&x${Size}) // Ok
|
|
opt_char_ptr_func(&x${Size}) // Ok
|
|
|
|
const_char_ptr_func(&x${Size}) // Ok
|
|
const_opt_char_ptr_func(&x${Size}) // Ok
|
|
|
|
int_${Size}_ptr_func(&x${Size}) // Ok
|
|
uint_${Size}_ptr_func(&x${Size}) // Ok
|
|
|
|
opt_int_${Size}_ptr_func(&x${Size}) // Ok
|
|
opt_uint_${Size}_ptr_func(&x${Size}) // Ok
|
|
|
|
const_int_${Size}_ptr_func(&x${Size}) // OK
|
|
const_uint_${Size}_ptr_func(&x${Size}) // OK
|
|
const_opt_int_${Size}_ptr_func(&x${Size}) // OK
|
|
const_opt_uint_${Size}_ptr_func(&x${Size}) // OK
|
|
% end
|
|
}
|
|
|
|
func test_array_to_pointer_conversion() {
|
|
% for Size in ['16', '32', '64']:
|
|
var x${Size}: [Int${Size}] = []
|
|
|
|
void_ptr_func(&x${Size}) // Ok
|
|
const_void_ptr_func(x${Size}) // Ok
|
|
opt_void_ptr_func(x${Size})
|
|
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutableRawPointer'}}
|
|
|
|
char_ptr_func(x${Size})
|
|
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<CChar>' (aka 'UnsafeMutablePointer<Int8>')}}
|
|
opt_char_ptr_func(x${Size})
|
|
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<CChar>' (aka 'UnsafeMutablePointer<Int8>')}}
|
|
|
|
const_char_ptr_func(x${Size}) // Ok
|
|
const_opt_char_ptr_func(x${Size}) // Ok
|
|
|
|
int_${Size}_ptr_func(x${Size})
|
|
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<Int${Size}>'}}
|
|
uint_${Size}_ptr_func(x${Size})
|
|
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<UInt${Size}>'}}
|
|
|
|
opt_int_${Size}_ptr_func(x${Size})
|
|
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<Int${Size}>'}}
|
|
opt_uint_${Size}_ptr_func(x${Size})
|
|
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<UInt${Size}>'}}
|
|
|
|
const_int_${Size}_ptr_func(x${Size}) // OK
|
|
const_uint_${Size}_ptr_func(x${Size}) // OK
|
|
const_opt_int_${Size}_ptr_func(x${Size}) // OK
|
|
const_opt_uint_${Size}_ptr_func(x${Size}) // OK
|
|
% end
|
|
}
|