diff --git a/stdlib/public/core/Bool.swift b/stdlib/public/core/Bool.swift index deaebcdecae4d..15f4b591f3f14 100644 --- a/stdlib/public/core/Bool.swift +++ b/stdlib/public/core/Bool.swift @@ -133,7 +133,6 @@ public struct Bool: Sendable { /// - Returns: Either `true` or `false`, randomly chosen with equal /// probability. @inlinable - @_unavailableInEmbedded public static func random() -> Bool { var g = SystemRandomNumberGenerator() return Bool.random(using: &g) diff --git a/stdlib/public/core/Collection.swift b/stdlib/public/core/Collection.swift index 3a090d10f0a22..14f6edf8b44b6 100644 --- a/stdlib/public/core/Collection.swift +++ b/stdlib/public/core/Collection.swift @@ -951,7 +951,6 @@ extension Collection { /// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the length /// of the collection. @inlinable - @_unavailableInEmbedded public func randomElement() -> Element? { var g = SystemRandomNumberGenerator() return randomElement(using: &g) diff --git a/stdlib/public/core/CollectionAlgorithms.swift b/stdlib/public/core/CollectionAlgorithms.swift index e9e215477aa75..f528c113ed9a3 100644 --- a/stdlib/public/core/CollectionAlgorithms.swift +++ b/stdlib/public/core/CollectionAlgorithms.swift @@ -571,7 +571,6 @@ extension Sequence { /// /// - Complexity: O(*n*), where *n* is the length of the sequence. @inlinable - @_unavailableInEmbedded public func shuffled() -> [Element] { var g = SystemRandomNumberGenerator() return shuffled(using: &g) @@ -630,7 +629,6 @@ extension MutableCollection where Self: RandomAccessCollection { /// /// - Complexity: O(*n*), where *n* is the length of the collection. @inlinable - @_unavailableInEmbedded public mutating func shuffle() { var g = SystemRandomNumberGenerator() shuffle(using: &g) diff --git a/stdlib/public/core/FloatingPointRandom.swift b/stdlib/public/core/FloatingPointRandom.swift index f8f8f5cb43929..8aeb16eb36030 100644 --- a/stdlib/public/core/FloatingPointRandom.swift +++ b/stdlib/public/core/FloatingPointRandom.swift @@ -108,7 +108,6 @@ extension BinaryFloatingPoint where Self.RawSignificand: FixedWidthInteger { /// `range` must be finite and non-empty. /// - Returns: A random value within the bounds of `range`. @inlinable - @_unavailableInEmbedded public static func random(in range: Range) -> Self { var g = SystemRandomNumberGenerator() return Self.random(in: range, using: &g) @@ -209,7 +208,6 @@ extension BinaryFloatingPoint where Self.RawSignificand: FixedWidthInteger { /// - Parameter range: The range in which to create a random value. Must be finite. /// - Returns: A random value within the bounds of `range`. @inlinable - @_unavailableInEmbedded public static func random(in range: ClosedRange) -> Self { var g = SystemRandomNumberGenerator() return Self.random(in: range, using: &g) diff --git a/stdlib/public/core/Integers.swift b/stdlib/public/core/Integers.swift index 148b3fa53513d..1d566c78a502c 100644 --- a/stdlib/public/core/Integers.swift +++ b/stdlib/public/core/Integers.swift @@ -2694,7 +2694,6 @@ extension FixedWidthInteger { /// `range` must not be empty. /// - Returns: A random value within the bounds of `range`. @inlinable - @_unavailableInEmbedded public static func random(in range: Range) -> Self { var g = SystemRandomNumberGenerator() return Self.random(in: range, using: &g) @@ -2767,7 +2766,6 @@ extension FixedWidthInteger { /// - Parameter range: The range in which to create a random value. /// - Returns: A random value within the bounds of `range`. @inlinable - @_unavailableInEmbedded public static func random(in range: ClosedRange) -> Self { var g = SystemRandomNumberGenerator() return Self.random(in: range, using: &g) diff --git a/stdlib/public/core/Random.swift b/stdlib/public/core/Random.swift index f7a9fac2d494d..d0895664ffdb0 100644 --- a/stdlib/public/core/Random.swift +++ b/stdlib/public/core/Random.swift @@ -147,7 +147,6 @@ extension RandomNumberGenerator { /// from `/dev/urandom`. /// - Windows uses `BCryptGenRandom`. @frozen -@_unavailableInEmbedded public struct SystemRandomNumberGenerator: RandomNumberGenerator, Sendable { /// Creates a new instance of the system's default random number generator. @inlinable diff --git a/stdlib/public/core/SIMDVector.swift b/stdlib/public/core/SIMDVector.swift index f34e483df67b9..1d046c3557131 100644 --- a/stdlib/public/core/SIMDVector.swift +++ b/stdlib/public/core/SIMDVector.swift @@ -565,7 +565,6 @@ extension SIMD where Scalar: FixedWidthInteger { /// Returns a vector with random values from within the specified range in /// all lanes, using the given generator as a source for randomness. - @_unavailableInEmbedded @inlinable public static func random( in range: Range, @@ -580,7 +579,6 @@ extension SIMD where Scalar: FixedWidthInteger { /// Returns a vector with random values from within the specified range in /// all lanes. - @_unavailableInEmbedded @inlinable public static func random(in range: Range) -> Self { var g = SystemRandomNumberGenerator() @@ -589,7 +587,6 @@ extension SIMD where Scalar: FixedWidthInteger { /// Returns a vector with random values from within the specified range in /// all lanes, using the given generator as a source for randomness. - @_unavailableInEmbedded @inlinable public static func random( in range: ClosedRange, @@ -604,7 +601,6 @@ extension SIMD where Scalar: FixedWidthInteger { /// Returns a vector with random values from within the specified range in /// all lanes. - @_unavailableInEmbedded @inlinable public static func random(in range: ClosedRange) -> Self { var g = SystemRandomNumberGenerator() @@ -637,7 +633,6 @@ extension SIMD where Scalar: FloatingPoint { } } -@_unavailableInEmbedded extension SIMD where Scalar: BinaryFloatingPoint, Scalar.RawSignificand: FixedWidthInteger { /// Returns a vector with random values from within the specified range in @@ -725,7 +720,6 @@ public struct SIMDMask: SIMD } } -@_unavailableInEmbedded extension SIMDMask { /// Returns a vector mask with `true` or `false` randomly assigned in each /// lane, using the given generator as a source for randomness. diff --git a/test/embedded/Inputs/linux-rng-support.c b/test/embedded/Inputs/linux-rng-support.c new file mode 100644 index 0000000000000..543da80572945 --- /dev/null +++ b/test/embedded/Inputs/linux-rng-support.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +#ifdef __linux__ + +ssize_t getrandom(void *buf, size_t len, unsigned int flags); + +void arc4random_buf(void *buf, size_t nbytes) { + while (nbytes > 0) { + ssize_t actual_nbytes = 0; + do { + actual_nbytes = getrandom(buf, nbytes, 0); + } while (actual_nbytes == -1 && errno == EINTR); + + if (actual_nbytes == -1) { + abort(); + } + + buf = (uint8_t *)(buf) + actual_nbytes; + nbytes -= actual_nbytes; + } +} + +#endif diff --git a/test/embedded/dependencies-random.swift b/test/embedded/dependencies-random.swift new file mode 100644 index 0000000000000..7df0f1b0fde8f --- /dev/null +++ b/test/embedded/dependencies-random.swift @@ -0,0 +1,74 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -parse-as-library -enable-experimental-feature Embedded %s -c -o %t/a.o + +// RUN: grep DEP\: %s | sed 's#// DEP\: ##' | sort > %t/allowed-dependencies.txt + +// Linux/ELF doesn't use the "_" prefix in symbol mangling. +// RUN: if [ %target-os == "linux-gnu" ]; then sed -E -i -e 's/^_(.*)$/\1/' %t/allowed-dependencies.txt; fi + +// RUN: %llvm-nm --undefined-only --format=just-symbols %t/a.o | sort | tee %t/actual-dependencies.txt + +// Fail if there is any entry in actual-dependencies.txt that's not in allowed-dependencies.txt +// RUN: test -z "`comm -13 %t/allowed-dependencies.txt %t/actual-dependencies.txt`" + +// DEP: ___stack_chk_fail +// DEP: ___stack_chk_guard +// DEP: _arc4random_buf +// DEP: _free +// DEP: _memset +// DEP: _putchar +// DEP: _posix_memalign + +// RUN: %target-clang -x c -c %S/Inputs/print.c -o %t/print.o +// RUN: %target-clang -x c -c %S/Inputs/linux-rng-support.c -o %t/linux-rng-support.o +// RUN: %target-clang %t/a.o %t/print.o %t/linux-rng-support.o -o %t/a.out +// RUN: %target-run %t/a.out | %FileCheck %s + +// REQUIRES: swift_in_compiler +// REQUIRES: executable_test +// REQUIRES: optimized_stdlib +// REQUIRES: OS=macosx || OS=linux-gnu +// UNSUPPORTED: OS=linux-gnu && CPU=aarch64 + +@_silgen_name("putchar") +@discardableResult +func putchar(_: CInt) -> CInt + +public func print(_ s: StaticString, terminator: StaticString = "\n") { + var p = s.utf8Start + while p.pointee != 0 { + putchar(CInt(p.pointee)) + p += 1 + } + p = terminator.utf8Start + while p.pointee != 0 { + putchar(CInt(p.pointee)) + p += 1 + } +} + +class MyClass { + func foo() { print("MyClass.foo") } +} + +class MySubClass: MyClass { + override func foo() { print("MySubClass.foo") } +} + +@main +struct Main { + static var objects: [MyClass] = [] + static func main() { + print("Hello Embedded Swift!") + // CHECK: Hello Embedded Swift! + objects.append(MyClass()) + objects.append(MySubClass()) + for o in objects { + o.foo() + } + // CHECK: MyClass.foo + // CHECK: MySubClass.foo + print(Bool.random() ? "you won" : "you lost") + // CHECK: you {{won|lost}} + } +} diff --git a/test/embedded/stdlib-array.swift b/test/embedded/stdlib-array.swift index 1e2a003b698a9..a7612060c2176 100644 --- a/test/embedded/stdlib-array.swift +++ b/test/embedded/stdlib-array.swift @@ -21,9 +21,9 @@ public func test() { array.max() array.partition(by: { $0 > 0 }) array.reduce(0, +) - // array.shuffle() - // array = array.shuffled() - // array.randomElement() + array.shuffle() + array = array.shuffled() + array.randomElement() } test() diff --git a/test/embedded/stdlib-random.swift b/test/embedded/stdlib-random.swift new file mode 100644 index 0000000000000..5804101618e5a --- /dev/null +++ b/test/embedded/stdlib-random.swift @@ -0,0 +1,17 @@ +// RUN: %target-swift-frontend -target armv7-apple-none-macho -Xcc -D__MACH__ -emit-ir %s -enable-experimental-feature Embedded | %FileCheck %s +// RUN: %target-swift-frontend -target arm64-apple-none-macho -Xcc -D__MACH__ -Xcc -D__arm64__ -Xcc -D__APPLE__ -emit-ir %s -enable-experimental-feature Embedded | %FileCheck %s + +// REQUIRES: swift_in_compiler +// REQUIRES: optimized_stdlib + +public func test() { + Bool.random() + Int.random(in: 0 ..< 100) + Double.random(in: 0.0 ..< 1.0) + [1, 2, 3].shuffled() + [1, 2, 3].randomElement() +} + +test() + +// CHECK: define {{.*}}i32 @main(i32 %0, ptr %1) diff --git a/test/embedded/stdlib-set.swift b/test/embedded/stdlib-set.swift index 32ab968cbdffd..02f60b29129f4 100644 --- a/test/embedded/stdlib-set.swift +++ b/test/embedded/stdlib-set.swift @@ -17,8 +17,8 @@ public func test() { s.min() s.max() s.reduce(0, +) - // s.shuffled() - // s.randomElement() + s.shuffled() + s.randomElement() } test()