cast-overflow.cpp revision 6d1862363c88c183b0ed7740fca876342cf0474b
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.
166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// XFAIL: armv7l-unknown-linux-gnueabihf
1758561700a4abad310911a24a867da49a14fae91eRichard Smith
186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if defined(__APPLE__)
196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# include <machine/endian.h>
206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BYTE_ORDER __DARWIN_BYTE_ORDER
216d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BIG_ENDIAN __DARWIN_BIG_ENDIAN
226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN
236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#elif defined(__FreeBSD__)
246d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# include <sys/endian.h>
256d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BYTE_ORDER _BYTE_ORDER
266d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BIG_ENDIAN _BIG_ENDIAN
276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define LITTLE_ENDIAN _LITTLE_ENDIAN
286d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#else
296d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# include <endian.h>
306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BYTE_ORDER __BYTE_ORDER
316d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define BIG_ENDIAN __BIG_ENDIAN
326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define LITTLE_ENDIAN __LITTLE_ENDIAN
336d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif  // __APPLE__
3458561700a4abad310911a24a867da49a14fae91eRichard Smith#include <stdint.h>
350a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#include <stdio.h>
3658561700a4abad310911a24a867da49a14fae91eRichard Smith#include <string.h>
3758561700a4abad310911a24a867da49a14fae91eRichard Smith
3858561700a4abad310911a24a867da49a14fae91eRichard Smithfloat Inf;
3958561700a4abad310911a24a867da49a14fae91eRichard Smithfloat NaN;
4058561700a4abad310911a24a867da49a14fae91eRichard Smith
4158561700a4abad310911a24a867da49a14fae91eRichard Smithint main(int argc, char **argv) {
4258561700a4abad310911a24a867da49a14fae91eRichard Smith  float MaxFloatRepresentableAsInt = 0x7fffff80;
4358561700a4abad310911a24a867da49a14fae91eRichard Smith  (int)MaxFloatRepresentableAsInt; // ok
4458561700a4abad310911a24a867da49a14fae91eRichard Smith  (int)-MaxFloatRepresentableAsInt; // ok
4558561700a4abad310911a24a867da49a14fae91eRichard Smith
4658561700a4abad310911a24a867da49a14fae91eRichard Smith  float MinFloatRepresentableAsInt = -0x7fffffff - 1;
4758561700a4abad310911a24a867da49a14fae91eRichard Smith  (int)MinFloatRepresentableAsInt; // ok
4858561700a4abad310911a24a867da49a14fae91eRichard Smith
4958561700a4abad310911a24a867da49a14fae91eRichard Smith  float MaxFloatRepresentableAsUInt = 0xffffff00u;
5058561700a4abad310911a24a867da49a14fae91eRichard Smith  (unsigned int)MaxFloatRepresentableAsUInt; // ok
5158561700a4abad310911a24a867da49a14fae91eRichard Smith
520a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#ifdef __SIZEOF_INT128__
5358561700a4abad310911a24a867da49a14fae91eRichard Smith  unsigned __int128 FloatMaxAsUInt128 = -((unsigned __int128)1 << 104);
5458561700a4abad310911a24a867da49a14fae91eRichard Smith  (void)(float)FloatMaxAsUInt128; // ok
550a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#endif
5658561700a4abad310911a24a867da49a14fae91eRichard Smith
57e20fa5c8c1788274da187ab1dfb8f110376d037dRichard Smith  float NearlyMinusOne = -0.99999;
58e20fa5c8c1788274da187ab1dfb8f110376d037dRichard Smith  unsigned Zero = NearlyMinusOne; // ok
59e20fa5c8c1788274da187ab1dfb8f110376d037dRichard Smith
6058561700a4abad310911a24a867da49a14fae91eRichard Smith  // Build a '+Inf'.
616d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if BYTE_ORDER == LITTLE_ENDIAN
6258561700a4abad310911a24a867da49a14fae91eRichard Smith  char InfVal[] = { 0x00, 0x00, 0x80, 0x7f };
636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#else
646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  char InfVal[] = { 0x7f, 0x80, 0x00, 0x00 };
656d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif
6658561700a4abad310911a24a867da49a14fae91eRichard Smith  float Inf;
6758561700a4abad310911a24a867da49a14fae91eRichard Smith  memcpy(&Inf, InfVal, 4);
6858561700a4abad310911a24a867da49a14fae91eRichard Smith
6958561700a4abad310911a24a867da49a14fae91eRichard Smith  // Build a 'NaN'.
706d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if BYTE_ORDER == LITTLE_ENDIAN
7158561700a4abad310911a24a867da49a14fae91eRichard Smith  char NaNVal[] = { 0x01, 0x00, 0x80, 0x7f };
726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#else
736d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  char NaNVal[] = { 0x7f, 0x80, 0x00, 0x01 };
746d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif
7558561700a4abad310911a24a867da49a14fae91eRichard Smith  float NaN;
7658561700a4abad310911a24a867da49a14fae91eRichard Smith  memcpy(&NaN, NaNVal, 4);
7758561700a4abad310911a24a867da49a14fae91eRichard Smith
78c446611d505593bb8e79ea98df87479e24cce68bRichard Smith  double DblInf = (double)Inf; // ok
79c446611d505593bb8e79ea98df87479e24cce68bRichard Smith
8058561700a4abad310911a24a867da49a14fae91eRichard Smith  switch (argv[1][0]) {
8158561700a4abad310911a24a867da49a14fae91eRichard Smith    // FIXME: Produce a source location for these checks and test for it here.
8258561700a4abad310911a24a867da49a14fae91eRichard Smith
8358561700a4abad310911a24a867da49a14fae91eRichard Smith    // Floating point -> integer overflow.
8458561700a4abad310911a24a867da49a14fae91eRichard Smith  case '0':
8558561700a4abad310911a24a867da49a14fae91eRichard Smith    // Note that values between 0x7ffffe00 and 0x80000000 may or may not
8658561700a4abad310911a24a867da49a14fae91eRichard Smith    // successfully round-trip, depending on the rounding mode.
877cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-0: runtime error: value 2.14748{{.*}} is outside the range of representable values of type 'int'
8858561700a4abad310911a24a867da49a14fae91eRichard Smith    return MaxFloatRepresentableAsInt + 0x80;
8958561700a4abad310911a24a867da49a14fae91eRichard Smith  case '1':
907cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-1: runtime error: value -2.14748{{.*}} is outside the range of representable values of type 'int'
9158561700a4abad310911a24a867da49a14fae91eRichard Smith    return MinFloatRepresentableAsInt - 0x100;
926d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  case '2': {
93e20fa5c8c1788274da187ab1dfb8f110376d037dRichard Smith    // CHECK-2: runtime error: value -1 is outside the range of representable values of type 'unsigned int'
946d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    volatile float f = -1.0;
956d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    volatile unsigned u = (unsigned)f;
966d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    return 0;
976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
9858561700a4abad310911a24a867da49a14fae91eRichard Smith  case '3':
997cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-3: runtime error: value 4.2949{{.*}} is outside the range of representable values of type 'unsigned int'
10058561700a4abad310911a24a867da49a14fae91eRichard Smith    return (unsigned)(MaxFloatRepresentableAsUInt + 0x100);
10158561700a4abad310911a24a867da49a14fae91eRichard Smith
10258561700a4abad310911a24a867da49a14fae91eRichard Smith  case '4':
1037cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-4: runtime error: value {{.*}} is outside the range of representable values of type 'int'
10458561700a4abad310911a24a867da49a14fae91eRichard Smith    return Inf;
10558561700a4abad310911a24a867da49a14fae91eRichard Smith  case '5':
1067cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-5: runtime error: value {{.*}} is outside the range of representable values of type 'int'
10758561700a4abad310911a24a867da49a14fae91eRichard Smith    return NaN;
10858561700a4abad310911a24a867da49a14fae91eRichard Smith
10958561700a4abad310911a24a867da49a14fae91eRichard Smith    // Integer -> floating point overflow.
11058561700a4abad310911a24a867da49a14fae91eRichard Smith  case '6':
1117cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-6: {{runtime error: value 0xffffff00000000000000000000000001 is outside the range of representable values of type 'float'|__int128 not supported}}
1120a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#ifdef __SIZEOF_INT128__
11358561700a4abad310911a24a867da49a14fae91eRichard Smith    return (float)(FloatMaxAsUInt128 + 1);
1140a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#else
1150a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith    puts("__int128 not supported");
1160a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith    return 0;
1170a7062f2cbb01b348bbc09be21a577957a2c68c2Richard Smith#endif
11858561700a4abad310911a24a867da49a14fae91eRichard Smith  // FIXME: The backend cannot lower __fp16 operations on x86 yet.
11958561700a4abad310911a24a867da49a14fae91eRichard Smith  //case '7':
12058561700a4abad310911a24a867da49a14fae91eRichard Smith  //  (__fp16)65504; // ok
1217cbd7e502e993320a3a1578179d336c268b80604Will Dietz  //  // CHECK-7: runtime error: value 65505 is outside the range of representable values of type '__fp16'
12258561700a4abad310911a24a867da49a14fae91eRichard Smith  //  return (__fp16)65505;
12358561700a4abad310911a24a867da49a14fae91eRichard Smith
12458561700a4abad310911a24a867da49a14fae91eRichard Smith    // Floating point -> floating point overflow.
12558561700a4abad310911a24a867da49a14fae91eRichard Smith  case '8':
1267cbd7e502e993320a3a1578179d336c268b80604Will Dietz    // CHECK-8: runtime error: value 1e+39 is outside the range of representable values of type 'float'
12758561700a4abad310911a24a867da49a14fae91eRichard Smith    return (float)1e39;
1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  case '9':
1292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    volatile long double ld = 300.0;
1302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // CHECK-9: runtime error: value 300 is outside the range of representable values of type 'char'
1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    char c = ld;
1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return c;
13358561700a4abad310911a24a867da49a14fae91eRichard Smith  }
13458561700a4abad310911a24a867da49a14fae91eRichard Smith}
135