|
| 1 | +// RUN: rm -rf %t |
| 2 | +// RUN: mkdir -p %t |
| 3 | +// RUN: %S/../../utils/gyb %s -o %t/FixedPointConversion.swift |
| 4 | +// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-build-swift %t/FixedPointConversion.swift -o %t/a.out_Debug |
| 5 | +// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-build-swift %t/FixedPointConversion.swift -o %t/a.out_Release -O |
| 6 | +// |
| 7 | +// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-run %t/a.out_Debug |
| 8 | +// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-run %t/a.out_Release |
| 9 | +// REQUIRES: executable_test |
| 10 | + |
| 11 | +%{ |
| 12 | +import gyb |
| 13 | +}% |
| 14 | + |
| 15 | +import StdlibUnittest |
| 16 | + |
| 17 | +var FixedPointConversionTraps = TestSuite("FixedPointToFixedPointConversionTraps") |
| 18 | +var FixedPointConversionFailure = TestSuite("FixedPointToFixedPointConversionFailures") |
| 19 | + |
| 20 | +%{ |
| 21 | + |
| 22 | +int_to_int_conversion_template = gyb.parse_template("int_to_int_conversion", |
| 23 | +""" |
| 24 | +%{ |
| 25 | +from SwiftIntTypes import all_integer_types |
| 26 | + |
| 27 | +def intMax(bits, signed): |
| 28 | + bits = bits - 1 if signed else bits |
| 29 | + return (1 << bits) - 1 |
| 30 | + |
| 31 | +def intMin(bits, signed): |
| 32 | + return -1 * intMax(bits, signed) - 1 if signed else 0 |
| 33 | + |
| 34 | +}% |
| 35 | + |
| 36 | +% for self_ty in all_integer_types(word_bits): |
| 37 | +% selfBits = self_ty.bits |
| 38 | +% selfSigned = self_ty.is_signed |
| 39 | +% selfMin = intMin(selfBits, selfSigned) |
| 40 | +% selfMax = intMax(selfBits, selfSigned) |
| 41 | +% Self = self_ty.stdlib_name |
| 42 | + |
| 43 | +% for other_ty in all_integer_types(word_bits): |
| 44 | +% otherBits = other_ty.bits |
| 45 | +% otherSigned = other_ty.is_signed |
| 46 | +% otherMin = intMin(otherBits, otherSigned) |
| 47 | +% otherMax = intMax(otherBits, otherSigned) |
| 48 | +% Other = other_ty.stdlib_name |
| 49 | + |
| 50 | +% for testValue in [selfMin, selfMax, selfMin - 1, selfMax + 1, otherMin, otherMax]: |
| 51 | + |
| 52 | +% if testValue < otherMin or testValue > otherMax: |
| 53 | +% # Can't construct `other` value, do nothing and continue. |
| 54 | + |
| 55 | +% elif testValue >= selfMin and testValue <= selfMax: |
| 56 | + |
| 57 | +/// Always-safe conversion from ${Other}(${testValue}) to ${Self}. |
| 58 | +FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") { |
| 59 | + // Test that nothing interesting happens and we end up with the same result after converting. |
| 60 | + let input = get${Other}(${testValue}) |
| 61 | + let result = ${Self}(input) |
| 62 | + expectEqual(${testValue}, result) |
| 63 | + _blackHole(result) |
| 64 | +} |
| 65 | + |
| 66 | +/// Never-nil failable conversion from ${Other}(${testValue}) to ${Self}. |
| 67 | +FixedPointConversionFailure.test("${Other}To${Self}FailableConversion/dest=${testValue}") { |
| 68 | + // Test that nothing interesting happens and we end up with a non-nil, identical result. |
| 69 | + let input = get${Other}(${testValue}) |
| 70 | + var result = ${Self}(exactly: input) |
| 71 | + expectNotEqual(result, nil) |
| 72 | + expectEqual(${testValue}, result) |
| 73 | + _blackHole(result) |
| 74 | +} |
| 75 | + |
| 76 | +% else: |
| 77 | + |
| 78 | +/// Always-failing conversion from ${Other}(${testValue}) to ${Self}. |
| 79 | +FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") { |
| 80 | + // Test that we check if we fail and crash when an integer would be truncated in conversion. |
| 81 | + let input = get${Other}(${testValue}) |
| 82 | + expectCrashLater() |
| 83 | + var result = ${Self}(input) |
| 84 | + _blackHole(result) |
| 85 | +} |
| 86 | + |
| 87 | +/// Always-nil failable conversion from ${Other}(${testValue}) to ${Self}. |
| 88 | +FixedPointConversionFailure.test("${Other}To${Self}Conversion/dest=${testValue}") { |
| 89 | + // Test that we check if we return nil when an integer would be truncated in conversion. |
| 90 | + let input = get${Other}(${testValue}) |
| 91 | + var result = ${Self}(exactly: input) |
| 92 | + expectEqual(nil, result) |
| 93 | + _blackHole(result) |
| 94 | +} |
| 95 | +% end |
| 96 | + |
| 97 | +% end # for testValue in ... |
| 98 | +% end # for in all_integer_types (Other) |
| 99 | +% end # for in all_integer_types (Self) |
| 100 | +""") |
| 101 | + |
| 102 | +}% |
| 103 | + |
| 104 | +#if arch(i386) || arch(arm) |
| 105 | + |
| 106 | + ${gyb.execute_template( |
| 107 | + int_to_int_conversion_template, |
| 108 | + word_bits=32)} |
| 109 | + |
| 110 | +#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) |
| 111 | + |
| 112 | + ${gyb.execute_template( |
| 113 | + int_to_int_conversion_template, |
| 114 | + word_bits=64)} |
| 115 | + |
| 116 | +#else |
| 117 | + |
| 118 | +_UnimplementedError() |
| 119 | + |
| 120 | +#endif |
| 121 | + |
| 122 | +runAllTests() |
0 commit comments