Home | History | Annotate | Download | only in Float
      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