16d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// FIXME: run this (and other) UBSan tests in both 32- and 64-bit modes (?).
249d29ed950f9e309a7b755b2a0601ed483ce3adePeter Collingbourne// RUN: %clangxx -fsanitize=float-cast-overflow %s -o %t
32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %run %t _
42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %run %t 0 2>&1 | FileCheck %s --check-prefix=CHECK-0
52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK-1
62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK-2
72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK-3
82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %run %t 4 2>&1 | FileCheck %s --check-prefix=CHECK-4
92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %run %t 5 2>&1 | FileCheck %s --check-prefix=CHECK-5
102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %run %t 6 2>&1 | FileCheck %s --check-prefix=CHECK-6
112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FIXME: %run %t 7 2>&1 | FileCheck %s --check-prefix=CHECK-7
126d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// FIXME: not %run %t 8 2>&1 | FileCheck %s --check-prefix=CHECK-8
136d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// RUN: not %run %t 9 2>&1 | FileCheck %s --check-prefix=CHECK-9
1458561700a4abad310911a24a867da49a14fae91eRichard Smith
1558561700a4abad310911a24a867da49a14fae91eRichard Smith// This test assumes float and double are IEEE-754 single- and double-precision.
1658561700a4abad310911a24a867da49a14fae91eRichard Smith
176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if defined(__APPLE__)
186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# include <machine/endian.h>
196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BYTE_ORDER __DARWIN_BYTE_ORDER
206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BIG_ENDIAN __DARWIN_BIG_ENDIAN
216d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN
226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#elif defined(__FreeBSD__)
236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# include <sys/endian.h>
246d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BYTE_ORDER _BYTE_ORDER
256d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BIG_ENDIAN _BIG_ENDIAN
266d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define LITTLE_ENDIAN _LITTLE_ENDIAN
276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#else
286d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# include <endian.h>
296d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BYTE_ORDER __BYTE_ORDER
306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BIG_ENDIAN __BIG_ENDIAN
316d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define LITTLE_ENDIAN __LITTLE_ENDIAN
326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif  // __APPLE__
3358561700a4abad310911a24a867da49a14fae91eRichard Smith#include <stdint.h>
340a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#include <stdio.h>
3558561700a4abad310911a24a867da49a14fae91eRichard Smith#include <string.h>
3658561700a4abad310911a24a867da49a14fae91eRichard Smith
3758561700a4abad310911a24a867da49a14fae91eRichard Smithfloat Inf;
3858561700a4abad310911a24a867da49a14fae91eRichard Smithfloat NaN;
3958561700a4abad310911a24a867da49a14fae91eRichard Smith
4058561700a4abad310911a24a867da49a14fae91eRichard Smithint main(int argc, char **argv) {
4158561700a4abad310911a24a867da49a14fae91eRichard Smith  float MaxFloatRepresentableAsInt = 0x7fffff80;
4258561700a4abad310911a24a867da49a14fae91eRichard Smith  (int)MaxFloatRepresentableAsInt; // ok
4358561700a4abad310911a24a867da49a14fae91eRichard Smith  (int)-MaxFloatRepresentableAsInt; // ok
4458561700a4abad310911a24a867da49a14fae91eRichard Smith
4558561700a4abad310911a24a867da49a14fae91eRichard Smith  float MinFloatRepresentableAsInt = -0x7fffffff - 1;
4658561700a4abad310911a24a867da49a14fae91eRichard Smith  (int)MinFloatRepresentableAsInt; // ok
4758561700a4abad310911a24a867da49a14fae91eRichard Smith
4858561700a4abad310911a24a867da49a14fae91eRichard Smith  float MaxFloatRepresentableAsUInt = 0xffffff00u;
4958561700a4abad310911a24a867da49a14fae91eRichard Smith  (unsigned int)MaxFloatRepresentableAsUInt; // ok
5058561700a4abad310911a24a867da49a14fae91eRichard Smith
510a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#ifdef __SIZEOF_INT128__
5258561700a4abad310911a24a867da49a14fae91eRichard Smith  unsigned __int128 FloatMaxAsUInt128 = -((unsigned __int128)1 << 104);
5358561700a4abad310911a24a867da49a14fae91eRichard Smith  (void)(float)FloatMaxAsUInt128; // ok
540a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#endif
5558561700a4abad310911a24a867da49a14fae91eRichard Smith
56e20fa5c8c1788274da187ab1dfb8f110376d037dRichard Smith  float NearlyMinusOne = -0.99999;
57e20fa5c8c1788274da187ab1dfb8f110376d037dRichard Smith  unsigned Zero = NearlyMinusOne; // ok
58e20fa5c8c1788274da187ab1dfb8f110376d037dRichard Smith
5958561700a4abad310911a24a867da49a14fae91eRichard Smith  // Build a '+Inf'.
606d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if BYTE_ORDER == LITTLE_ENDIAN
6158561700a4abad310911a24a867da49a14fae91eRichard Smith  char InfVal[] = { 0x00, 0x00, 0x80, 0x7f };
626d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#else
636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  char InfVal[] = { 0x7f, 0x80, 0x00, 0x00 };
646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif
6558561700a4abad310911a24a867da49a14fae91eRichard Smith  float Inf;
6658561700a4abad310911a24a867da49a14fae91eRichard Smith  memcpy(&Inf, InfVal, 4);
6758561700a4abad310911a24a867da49a14fae91eRichard Smith
6858561700a4abad310911a24a867da49a14fae91eRichard Smith  // Build a 'NaN'.
696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if BYTE_ORDER == LITTLE_ENDIAN
7058561700a4abad310911a24a867da49a14fae91eRichard Smith  char NaNVal[] = { 0x01, 0x00, 0x80, 0x7f };
716d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#else
726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  char NaNVal[] = { 0x7f, 0x80, 0x00, 0x01 };
736d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif
7458561700a4abad310911a24a867da49a14fae91eRichard Smith  float NaN;
7558561700a4abad310911a24a867da49a14fae91eRichard Smith  memcpy(&NaN, NaNVal, 4);
7658561700a4abad310911a24a867da49a14fae91eRichard Smith
77c446611d505593bb8e79ea98df87479e24cce68bRichard Smith  double DblInf = (double)Inf; // ok
78c446611d505593bb8e79ea98df87479e24cce68bRichard Smith
7958561700a4abad310911a24a867da49a14fae91eRichard Smith  switch (argv[1][0]) {
8058561700a4abad310911a24a867da49a14fae91eRichard Smith    // FIXME: Produce a source location for these checks and test for it here.
8158561700a4abad310911a24a867da49a14fae91eRichard Smith
8258561700a4abad310911a24a867da49a14fae91eRichard Smith    // Floating point -> integer overflow.
83909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar  case '0': {
8458561700a4abad310911a24a867da49a14fae91eRichard Smith    // Note that values between 0x7ffffe00 and 0x80000000 may or may not
8558561700a4abad310911a24a867da49a14fae91eRichard Smith    // successfully round-trip, depending on the rounding mode.
867cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-0: runtime error: value 2.14748{{.*}} is outside the range of representable values of type 'int'
87909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar    static int test_int = MaxFloatRepresentableAsInt + 0x80;
88909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar    return 0;
89909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar    }
9058561700a4abad310911a24a867da49a14fae91eRichard Smith  case '1':
917cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-1: runtime error: value -2.14748{{.*}} is outside the range of representable values of type 'int'
9258561700a4abad310911a24a867da49a14fae91eRichard Smith    return MinFloatRepresentableAsInt - 0x100;
936d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  case '2': {
94e20fa5c8c1788274da187ab1dfb8f110376d037dRichard Smith    // CHECK-2: runtime error: value -1 is outside the range of representable values of type 'unsigned int'
956d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    volatile float f = -1.0;
966d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    volatile unsigned u = (unsigned)f;
976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    return 0;
986d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
99909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar  case '3': {
1007cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-3: runtime error: value 4.2949{{.*}} is outside the range of representable values of type 'unsigned int'
101909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar    static int test_int = (unsigned)(MaxFloatRepresentableAsUInt + 0x100);
102909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar    return 0;
103909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar  }
10458561700a4abad310911a24a867da49a14fae91eRichard Smith
105909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar  case '4': {
1067cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-4: runtime error: value {{.*}} is outside the range of representable values of type 'int'
107909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar    static int test_int = Inf;
108909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar    return 0;
109909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar  }
11058561700a4abad310911a24a867da49a14fae91eRichard Smith  case '5':
1117cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-5: runtime error: value {{.*}} is outside the range of representable values of type 'int'
11258561700a4abad310911a24a867da49a14fae91eRichard Smith    return NaN;
11358561700a4abad310911a24a867da49a14fae91eRichard Smith
11458561700a4abad310911a24a867da49a14fae91eRichard Smith    // Integer -> floating point overflow.
115909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar  case '6': {
1167cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-6: {{runtime error: value 0xffffff00000000000000000000000001 is outside the range of representable values of type 'float'|__int128 not supported}}
1170a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#ifdef __SIZEOF_INT128__
118909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar    static int test_int = (float)(FloatMaxAsUInt128 + 1);
119909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar    return 0;
1200a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#else
1210a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith    puts("__int128 not supported");
1220a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith    return 0;
1230a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#endif
124909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar  }
12558561700a4abad310911a24a867da49a14fae91eRichard Smith  // FIXME: The backend cannot lower __fp16 operations on x86 yet.
12658561700a4abad310911a24a867da49a14fae91eRichard Smith  //case '7':
12758561700a4abad310911a24a867da49a14fae91eRichard Smith  //  (__fp16)65504; // ok
1287cbd7e502e993320a3a1578179d336c268b80604Will Dietz  //  // CHECK-7: runtime error: value 65505 is outside the range of representable values of type '__fp16'
12958561700a4abad310911a24a867da49a14fae91eRichard Smith  //  return (__fp16)65505;
13058561700a4abad310911a24a867da49a14fae91eRichard Smith
13158561700a4abad310911a24a867da49a14fae91eRichard Smith    // Floating point -> floating point overflow.
13258561700a4abad310911a24a867da49a14fae91eRichard Smith  case '8':
1337cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-8: runtime error: value 1e+39 is outside the range of representable values of type 'float'
13458561700a4abad310911a24a867da49a14fae91eRichard Smith    return (float)1e39;
1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  case '9':
1362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    volatile long double ld = 300.0;
1372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // CHECK-9: runtime error: value 300 is outside the range of representable values of type 'char'
1382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    char c = ld;
1392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return c;
14058561700a4abad310911a24a867da49a14fae91eRichard Smith  }
14158561700a4abad310911a24a867da49a14fae91eRichard Smith}
142