Skip to content

Commit 70e1931

Browse files
committed
[Stdlib] Make alignedStorageForEmptyVaLists bigger.
Expand alignedStorageForEmptyVaLists to eight Doubles. This produces more predictable output for code that calls a variadic function without parameters where the function still expects them, such as passing an arbitary string to a string formatting function. It's still unsound, but this makes it more predictable. rdar://145083971
1 parent a172489 commit 70e1931

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

stdlib/public/core/VarArgs.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,14 @@ final internal class __VaListBuilder {
715715
internal var retainer = [CVarArg]()
716716
#endif
717717

718-
internal static var alignedStorageForEmptyVaLists: Double = 0
718+
// Some code will call a variadic function without passing variadic parameters
719+
// where the function will still attempt to read variadic parameters. For
720+
// example, calling printf with an arbitrary string as the format string. This
721+
// is inherently unsound, but we'll try to be nice to such code by giving it
722+
// 64 bytes of zeroes in that case.
723+
internal static var alignedStorageForEmptyVaLists:
724+
(Double, Double, Double, Double, Double, Double, Double, Double)
725+
= (0, 0, 0, 0, 0, 0, 0, 0)
719726
}
720727

721728
#endif

test/stdlib/VarArgs.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,20 @@ func test_varArgs6() {
172172
}
173173
test_varArgs6()
174174

175+
func test_varArgs7() {
176+
#if canImport(Darwin) && arch(arm64)
177+
// Test a workaround for format specifiers and no arguments. We supply eight
178+
// words of zeroed memory to give this predictable behavior.
179+
my_printf("No parameters: %ld %ld %ld %ld %ld %ld %ld %ld\n")
180+
#else
181+
// va_list is more complicated on other targets so that behavior is not the
182+
// same, skip the test by doing a fake print of the expected output.
183+
my_printf("No parameters: 0 0 0 0 0 0 0 0\n")
184+
#endif
185+
// CHECK: No parameters: 0 0 0 0 0 0 0 0
186+
}
187+
test_varArgs7()
188+
175189

176190
// CHECK: done.
177191
my_printf("done.")

0 commit comments

Comments
 (0)