-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Open
Labels
c++ interopFeature: Interoperability with C++Feature: Interoperability with C++
Description
Swift is silently miscompiling .pointee
on a C++ std::optional
value on Linux:
TestSuite.test("abc") {
var optBoolT = StdOptionalBool(true)
var optBoolF = StdOptionalBool(true)
expectTrue(optBoolT.pointee) // passes
expectTrue(optBoolF.pointee) // fails
}
Looking at SILGen, looks like we have a use-after-free in the implicitly generated getter for var pointee
:
// std.optional<CBool>.pointee.getter
// Isolation: unspecified
sil shared [transparent] [serialized] [ossa] @$sSo3stdO0021optionalCBool_pgFEdJaV7pointeeSbvg : $@convention(method) (std.optional<CBool>) -> Bool {
// %0 "self" // users: %3, %1
bb0(%0 : $std.optional<CBool>):
debug_value %0, let, name "self", argno 1 // id: %1
%2 = alloc_stack $std.optional<CBool> // users: %6, %5, %3
store %0 to [trivial] %2 // id: %3
// function_ref _ZNKOSt8optionalIbEdeEv
%4 = function_ref @_ZNKOSt8optionalIbEdeEv : $@convention(cxx_method) (@in_guaranteed std.optional<CBool>) -> UnsafePointer<Bool> // user: %5
%5 = apply %4(%2) : $@convention(cxx_method) (@in_guaranteed std.optional<CBool>) -> UnsafePointer<Bool> // users: %11, %8
dealloc_stack %2 // id: %6
// function_ref UnsafePointer<>.pointee.unsafeAddressor
%7 = function_ref @$sSPsRi_zrlE7pointeexvlu : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafePointer<τ_0_0>) -> UnsafePointer<τ_0_0> // user: %8
%8 = apply %7<Bool>(%5) : $@convention(method) <τ_0_0 where τ_0_0 : ~Copyable> (UnsafePointer<τ_0_0>) -> UnsafePointer<τ_0_0> // user: %9
%9 = struct_extract %8, #UnsafePointer._rawValue // user: %10
%10 = pointer_to_address %9 to [strict] $*Bool // user: %11
Notice that we're creating an implicit copy of the std::optional
, getting a pointer out of it, and then deallocating the implicit copy (dealloc_stack %2
) before retrieving the value out of the pointer (%9 = struct_extract %8
).
I discovered this while working on #74146 but this issue isn't specific to that patch.
Metadata
Metadata
Assignees
Labels
c++ interopFeature: Interoperability with C++Feature: Interoperability with C++