Hi all, I’m experiencing just the weirdest bug. It seems like maybe a miscompile to me (or I've totally misunderstood vDSP.clear), but it’s at the crossroads of non-copyable types, the Accelerate framework, and thread sanitizer. So I’m not really sure where I should be filing this. Maybe you can help?
I have a test case where a struct’s deinit
is called twice, leading to memory corruption. This only happens when compiled for release with thread sanitizer. Simplified version below:
// Run this with swiftc -sanitize=thread test.swift && ./test
import Accelerate
struct Testable: ~Copyable {
var foo = 999
init() { print("Initing...") }
func honk() {
print(foo)
}
deinit { print("Deinit!") }
}
struct Thing: ~Copyable {
var buffer: UnsafeMutableBufferPointer<Float>
var t: Testable
init() {
buffer = .allocate(capacity: 100)
vDSP.clear(&buffer)
t = Testable()
}
func test() {
t.honk()
}
deinit {
buffer.deallocate()
}
}
Thing().test()
This prints
Deinit!
Initing...
999
Deinit!
I think the first "Deinit" line shouldn't appear. If I remove either of the following, the first "Deinit" goes away:
vDSP.clear(&buffer)
-sanitize=thread
from the swiftc invocation
Address sanitizer shows no issue (and doesn't reproduce the issue).
Swift information:
$ swiftc --version
swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0
Run on macOS Sonoma 14.5.