mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
243 lines
7.7 KiB
Plaintext
243 lines
7.7 KiB
Plaintext
// RUN: %empty-directory(%t)
|
|
// RUN: %S/../../utils/gyb %s -o %t/FixedPointConversion.swift
|
|
// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-build-swift %t/FixedPointConversion.swift -o %t/a.out_Debug -Onone
|
|
// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-build-swift %t/FixedPointConversion.swift -o %t/a.out_Release -O
|
|
//
|
|
// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-run %t/a.out_Debug
|
|
// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-run %t/a.out_Release
|
|
// REQUIRES: executable_test
|
|
|
|
// FIXME(integers): add tests that perform the same checks in generic code
|
|
|
|
%{
|
|
import gyb
|
|
}%
|
|
|
|
import StdlibUnittest
|
|
|
|
var FixedPointConversionTraps = TestSuite("FixedPointToFixedPointConversionTraps")
|
|
var FixedPointConversionFailure = TestSuite("FixedPointToFixedPointConversionFailures")
|
|
|
|
var FloatingPointConversionTruncations = TestSuite("FloatingPointToFixedPointConversionTruncations")
|
|
var FloatingPointConversionTraps = TestSuite("FloatingPointConversionTraps")
|
|
var FloatingPointConversionFailures = TestSuite("FloatingPointToFixedPointConversionFailures")
|
|
|
|
func getInfiniteOrNaNMessage() -> String {
|
|
if _isDebugAssertConfiguration() {
|
|
return "either infinite or NaN"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func getTooSmallMessage() -> String {
|
|
if _isDebugAssertConfiguration() {
|
|
return "would be less than"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func getTooLargeMessage() -> String {
|
|
if _isDebugAssertConfiguration() {
|
|
return "would be greater than"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
%{
|
|
|
|
int_to_int_conversion_template = gyb.parse_template("int_to_int_conversion",
|
|
"""
|
|
%{
|
|
from SwiftIntTypes import all_integer_types, int_max, int_min
|
|
from SwiftFloatingPointTypes import all_floating_point_types
|
|
|
|
}%
|
|
% for self_ty in all_integer_types(word_bits):
|
|
% selfBits = self_ty.bits
|
|
% selfSigned = self_ty.is_signed
|
|
% selfMin = self_ty.min
|
|
% selfMax = self_ty.max
|
|
% Self = self_ty.stdlib_name
|
|
|
|
% for other_ty in all_integer_types(word_bits):
|
|
% otherBits = other_ty.bits
|
|
% otherSigned = other_ty.is_signed
|
|
% otherMin = other_ty.min
|
|
% otherMax = other_ty.max
|
|
% Other = other_ty.stdlib_name
|
|
|
|
% for testValue in [selfMin, selfMax, selfMin - 1, selfMax + 1, otherMin, otherMax]:
|
|
|
|
% if testValue < otherMin or testValue > otherMax:
|
|
% # Can't construct `other` value, do nothing and continue.
|
|
|
|
% elif testValue >= selfMin and testValue <= selfMax:
|
|
|
|
/// Always-safe conversion from ${Other}(${testValue}) to ${Self}.
|
|
FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") {
|
|
// Test that nothing interesting happens and we end up with the same result after converting.
|
|
let input = get${Other}(${testValue})
|
|
expectEqual(${testValue}, ${Self}(input))
|
|
}
|
|
|
|
/// Never-nil failable conversion from ${Other}(${testValue}) to ${Self}.
|
|
FixedPointConversionFailure.test("${Other}To${Self}FailableConversion/dest=${testValue}") {
|
|
// Test that nothing interesting happens and we end up with a non-nil, identical result.
|
|
let input = get${Other}(${testValue})
|
|
var result = ${Self}(exactly: input)
|
|
expectEqual(${testValue}, result)
|
|
}
|
|
|
|
% else:
|
|
|
|
/// Always-failing conversion from ${Other}(${testValue}) to ${Self}.
|
|
FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") {
|
|
// Test that we check if we fail and crash when an integer would be truncated in conversion.
|
|
let input = get${Other}(${testValue})
|
|
expectCrashLater()
|
|
var result = ${Self}(input)
|
|
_blackHole(result)
|
|
}
|
|
|
|
/// Always-nil failable conversion from ${Other}(${testValue}) to ${Self}.
|
|
FixedPointConversionFailure.test("${Other}To${Self}Conversion/dest=${testValue}") {
|
|
// Test that we check if we return nil when an integer would be truncated in conversion.
|
|
let input = get${Other}(${testValue})
|
|
expectNil(${Self}(exactly: input))
|
|
}
|
|
% end
|
|
|
|
% end # for testValue in ...
|
|
% end # for in all_integer_types (Other)
|
|
|
|
% for other_type in all_floating_point_types():
|
|
% Other = "Float" + str(other_type.bits)
|
|
% otherMin = -int_max(bits=other_type.explicit_significand_bits, signed=False)
|
|
% otherMax = int_max(bits=other_type.explicit_significand_bits, signed=False)
|
|
|
|
% if Other == 'Float80':
|
|
#if !os(Windows) && (arch(i386) || arch(x86_64))
|
|
% end
|
|
|
|
% for testValue in [repr(value) for value in [selfMin, selfMax, selfMin - 0.1, selfMax + 0.1, otherMin, otherMax, 0.0, -0.0, 0.1, -0.1]]:
|
|
|
|
% if testValue < otherMin or testValue > otherMax:
|
|
% # Can't construct `other` value to test from, do nothing and continue.
|
|
|
|
% elif testValue >= selfMin and testValue <= selfMax and testValue % 1 == 0 and testValue != -0.0:
|
|
|
|
FloatingPointConversionTruncations.test("${Other}To${Self}Conversion/dest=${testValue}") {
|
|
let input = get${Other}(${testValue})
|
|
let result = ${Self}(input)
|
|
var resultConvertedBack = ${Other}(result)
|
|
expectEqual(${testValue}, resultConvertedBack)
|
|
}
|
|
|
|
FloatingPointConversionFailures.test("${Other}To${Self}FailableConversion/dest=${testValue}") {
|
|
let input = get${Other}(${testValue})
|
|
expectNil(${Self}(exactly: input))
|
|
}
|
|
|
|
% else:
|
|
|
|
% if testValue > selfMax:
|
|
FloatingPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}")
|
|
.crashOutputMatches(getTooLargeMessage()).code {
|
|
expectCrashLater()
|
|
% elif testValue < selfMin:
|
|
FloatingPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}")
|
|
.crashOutputMatches(getTooSmallMessage()).code {
|
|
expectCrashLater()
|
|
% else:
|
|
FloatingPointConversionTruncations.test("${Other}To${Self}Conversion/dest=${testValue}") {
|
|
% end
|
|
let input = get${Other}(${testValue})
|
|
var result = ${Self}(input)
|
|
var resultConvertedBack = ${Other}(result)
|
|
expectNotEqual(input, resultConvertedBack)
|
|
}
|
|
|
|
FloatingPointConversionFailures.test("${Other}To${Self}Conversion/dest=${testValue}") {
|
|
let input = get${Other}(${testValue})
|
|
expectNil(${Self}(exactly: input))
|
|
}
|
|
% end
|
|
% end # for in testValues
|
|
|
|
// Test Always-Trapping conversions.
|
|
|
|
% if not selfSigned:
|
|
|
|
FloatingPointConversionTraps.test("${Self}/${Other}/negative")
|
|
.crashOutputMatches(getTooSmallMessage()).code {
|
|
expectCrashLater()
|
|
_blackHole(${Self}(get${Other}(-123.0)))
|
|
}
|
|
|
|
FloatingPointConversionFailures.test("${Self}/${Other}/negative") {
|
|
expectNil(${Self}(exactly: get${Other}(-123.0)))
|
|
}
|
|
|
|
% end
|
|
|
|
FloatingPointConversionTraps.test("${Self}/${Other}/+inf")
|
|
.crashOutputMatches(getInfiniteOrNaNMessage()).code {
|
|
expectCrashLater()
|
|
_blackHole(${Self}(get${Other}(${Other}.infinity)))
|
|
}
|
|
|
|
FloatingPointConversionFailures.test("${Self}/${Other}/+inf") {
|
|
expectNil(${Self}(exactly: get${Other}(${Other}.infinity)))
|
|
}
|
|
|
|
FloatingPointConversionTraps.test("${Self}/${Other}/-inf")
|
|
.crashOutputMatches(getInfiniteOrNaNMessage()).code {
|
|
expectCrashLater()
|
|
_blackHole(${Self}(get${Other}(-${Other}.infinity)))
|
|
}
|
|
|
|
FloatingPointConversionFailures.test("${Self}/${Other}/-inf") {
|
|
expectNil(${Self}(exactly: get${Other}(-${Other}.infinity)))
|
|
}
|
|
|
|
FloatingPointConversionTraps.test("${Self}/${Other}/NaN")
|
|
.crashOutputMatches(getInfiniteOrNaNMessage()).code {
|
|
expectCrashLater()
|
|
_blackHole(${Self}(get${Other}(${Other}.nan)))
|
|
}
|
|
|
|
FloatingPointConversionFailures.test("${Self}/${Other}/NaN") {
|
|
expectNil(${Self}(exactly: get${Other}(${Other}.nan)))
|
|
}
|
|
|
|
% if Other == 'Float80':
|
|
#endif
|
|
% end
|
|
|
|
% end # for in all_floating_point_types (Other)
|
|
% end # for in all_integer_types (Self)
|
|
|
|
""")
|
|
|
|
}%
|
|
|
|
#if arch(i386) || arch(arm)
|
|
|
|
${gyb.execute_template(
|
|
int_to_int_conversion_template,
|
|
word_bits=32)}
|
|
|
|
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
|
|
|
|
${gyb.execute_template(
|
|
int_to_int_conversion_template,
|
|
word_bits=64)}
|
|
|
|
#else
|
|
|
|
_UnimplementedError()
|
|
|
|
#endif
|
|
|
|
runAllTests()
|