1 // RUN: %clang -fsanitize=float-cast-overflow %s -o %t 2 // RUN: %t _ 3 // RUN: %t 0 2>&1 | FileCheck %s --check-prefix=CHECK-0 4 // RUN: %t 1 2>&1 | FileCheck %s --check-prefix=CHECK-1 5 // RUN: %t 2 2>&1 | FileCheck %s --check-prefix=CHECK-2 6 // RUN: %t 3 2>&1 | FileCheck %s --check-prefix=CHECK-3 7 // RUN: %t 4 2>&1 | FileCheck %s --check-prefix=CHECK-4 8 // RUN: %t 5 2>&1 | FileCheck %s --check-prefix=CHECK-5 9 // RUN: %t 6 2>&1 | FileCheck %s --check-prefix=CHECK-6 10 // FIXME: %t 7 2>&1 | FileCheck %s --check-prefix=CHECK-7 11 // RUN: %t 8 2>&1 | FileCheck %s --check-prefix=CHECK-8 12 13 // This test assumes float and double are IEEE-754 single- and double-precision. 14 15 #include <stdint.h> 16 #include <stdio.h> 17 #include <string.h> 18 19 float Inf; 20 float NaN; 21 22 int main(int argc, char **argv) { 23 float MaxFloatRepresentableAsInt = 0x7fffff80; 24 (int)MaxFloatRepresentableAsInt; // ok 25 (int)-MaxFloatRepresentableAsInt; // ok 26 27 float MinFloatRepresentableAsInt = -0x7fffffff - 1; 28 (int)MinFloatRepresentableAsInt; // ok 29 30 float MaxFloatRepresentableAsUInt = 0xffffff00u; 31 (unsigned int)MaxFloatRepresentableAsUInt; // ok 32 33 #ifdef __SIZEOF_INT128__ 34 unsigned __int128 FloatMaxAsUInt128 = -((unsigned __int128)1 << 104); 35 (void)(float)FloatMaxAsUInt128; // ok 36 #endif 37 38 float NearlyMinusOne = -0.99999; 39 unsigned Zero = NearlyMinusOne; // ok 40 41 // Build a '+Inf'. 42 char InfVal[] = { 0x00, 0x00, 0x80, 0x7f }; 43 float Inf; 44 memcpy(&Inf, InfVal, 4); 45 46 // Build a 'NaN'. 47 char NaNVal[] = { 0x01, 0x00, 0x80, 0x7f }; 48 float NaN; 49 memcpy(&NaN, NaNVal, 4); 50 51 double DblInf = (double)Inf; // ok 52 53 switch (argv[1][0]) { 54 // FIXME: Produce a source location for these checks and test for it here. 55 56 // Floating point -> integer overflow. 57 case '0': 58 // Note that values between 0x7ffffe00 and 0x80000000 may or may not 59 // successfully round-trip, depending on the rounding mode. 60 // CHECK-0: runtime error: value 2.14748{{.*}} is outside the range of representable values of type 'int' 61 return MaxFloatRepresentableAsInt + 0x80; 62 case '1': 63 // CHECK-1: runtime error: value -2.14748{{.*}} is outside the range of representable values of type 'int' 64 return MinFloatRepresentableAsInt - 0x100; 65 case '2': 66 // CHECK-2: runtime error: value -1 is outside the range of representable values of type 'unsigned int' 67 return (unsigned)-1.0; 68 case '3': 69 // CHECK-3: runtime error: value 4.2949{{.*}} is outside the range of representable values of type 'unsigned int' 70 return (unsigned)(MaxFloatRepresentableAsUInt + 0x100); 71 72 case '4': 73 // CHECK-4: runtime error: value {{.*}} is outside the range of representable values of type 'int' 74 return Inf; 75 case '5': 76 // CHECK-5: runtime error: value {{.*}} is outside the range of representable values of type 'int' 77 return NaN; 78 79 // Integer -> floating point overflow. 80 case '6': 81 // CHECK-6: {{runtime error: value 0xffffff00000000000000000000000001 is outside the range of representable values of type 'float'|__int128 not supported}} 82 #ifdef __SIZEOF_INT128__ 83 return (float)(FloatMaxAsUInt128 + 1); 84 #else 85 puts("__int128 not supported"); 86 return 0; 87 #endif 88 // FIXME: The backend cannot lower __fp16 operations on x86 yet. 89 //case '7': 90 // (__fp16)65504; // ok 91 // // CHECK-7: runtime error: value 65505 is outside the range of representable values of type '__fp16' 92 // return (__fp16)65505; 93 94 // Floating point -> floating point overflow. 95 case '8': 96 // CHECK-8: runtime error: value 1e+39 is outside the range of representable values of type 'float' 97 return (float)1e39; 98 } 99 } 100