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