Skip to content

Commit 65c7d14

Browse files
Conform Float80 to CVarArgs when available. (swiftlang#20122)
When I added support for importing long double as Float80 on Intel, I neglected to conform it to CVarArgs. This patch fixes that, which most importantly lets users use String(format:) with Float80 values.
1 parent 5c6eacd commit 65c7d14

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

stdlib/public/core/VarArgs.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,25 @@ extension Double : _CVarArgPassedAsDouble, _CVarArgAligned {
383383
}
384384
}
385385

386+
#if !os(Windows) && (arch(i386) || arch(x86_64))
387+
extension Float80 : CVarArg, _CVarArgAligned {
388+
/// Transform `self` into a series of machine words that can be
389+
/// appropriately interpreted by C varargs.
390+
@inlinable // FIXME(sil-serialize-all)
391+
public var _cVarArgEncoding: [Int] {
392+
return _encodeBitsAsWords(self)
393+
}
394+
395+
/// Returns the required alignment in bytes of
396+
/// the value returned by `_cVarArgEncoding`.
397+
@inlinable // FIXME(sil-serialize-all)
398+
public var _cVarArgAlignment: Int {
399+
// FIXME: alignof differs from the ABI alignment on some architectures
400+
return MemoryLayout.alignment(ofValue: self)
401+
}
402+
}
403+
#endif
404+
386405
#if arch(x86_64) || arch(s390x)
387406

388407
/// An object that can manage the lifetime of storage backing a

test/stdlib/VarArgs.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,21 @@ func test_varArgs5() {
123123
}
124124
test_varArgs5()
125125

126+
#if !os(Windows) && (arch(i386) || arch(x86_64))
127+
func test_varArgs6() {
128+
// Verify alignment of va_list contents when `Float80` is present.
129+
let i8 = Int8(1)
130+
let f32 = Float(1.1)
131+
let f64 = Double(2.2)
132+
let f80 = Float80(4.5)
133+
my_printf("a %g %d %g %d %Lg %d %g a\n", f32, i8, f64, i8, f80, i8, f32)
134+
my_printf("b %d %g %d %g %d %Lg %d %g b\n", i8, f32, i8, f64, i8, f80, i8, f32)
135+
// CHECK: a 1.1 1 2.2 1 4.5 1 1.1 a
136+
// CHECK: b 1 1.1 1 2.2 1 4.5 1 1.1 b
137+
}
138+
test_varArgs6()
139+
#endif
140+
126141

127142
// CHECK: done.
128143
print("done.")

0 commit comments

Comments
 (0)