brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.0 KiB · 5aa4e25 Raw
476 lines · cpp
1// RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple x86_64-linux-gnu -fexperimental-new-constant-interpreter %s2// RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple armv8 -fexperimental-new-constant-interpreter %s3// RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu -fexperimental-new-constant-interpreter %s4// RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter -triple powerpc64le-unknown-unknown -mabi=ieeelongdouble %s5// RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter -triple powerpc64-unknown-unknown -mabi=ieeelongdouble %s6 7#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__8#  define LITTLE_END 19#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__10#  define LITTLE_END 011#else12#  error "huh?"13#endif14 15typedef decltype(nullptr) nullptr_t;16typedef __INTPTR_TYPE__ intptr_t;17typedef unsigned __INT16_TYPE__ uint16_t;18typedef unsigned __INT32_TYPE__ uint32_t;19typedef unsigned __INT64_TYPE__ uint64_t;20 21static_assert(sizeof(int) == 4);22static_assert(sizeof(long long) == 8);23 24template <class To, class From>25constexpr To bit_cast(const From &from) {26  static_assert(sizeof(To) == sizeof(From));27  return __builtin_bit_cast(To, from);28}29 30template <class Intermediate, class Init>31constexpr bool check_round_trip(const Init &init) {32  return bit_cast<Init>(bit_cast<Intermediate>(init)) == init;33}34 35template <class Intermediate, class Init>36constexpr Init round_trip(const Init &init) {37  return bit_cast<Init>(bit_cast<Intermediate>(init));38}39 40namespace std {41enum byte : unsigned char {};42} // namespace std43 44template <int N, typename T = unsigned char, int Pad = 0>45struct bits {46  T : Pad;47  T bits : N;48 49  constexpr bool operator==(const T& rhs) const {50    return bits == rhs;51  }52};53 54template <int N, typename T, int P>55constexpr bool operator==(const struct bits<N, T, P>& lhs, const struct bits<N, T, P>& rhs) {56  return lhs.bits == rhs.bits;57}58 59template<int N>60struct bytes {61  using size_t = unsigned int;62  unsigned char d[N];63 64  constexpr unsigned char operator[](size_t index) {65    if (index < N)66      return d[index]; // expected-note {{read of uninitialized object}}67    return -1;68  }69};70 71namespace Sanity {72  /// This is just one byte, and we extract 2 bits from it.73  ///74  /// 3 is 0000'0011.75  /// For both LE and BE, the buffer will contain exactly that76  /// byte, unaltered and not reordered in any way. It contains all 8 bits.77  static_assert(__builtin_bit_cast(bits<2>, (unsigned char)3) == (LITTLE_END ? 3 : 0));78 79  /// Similarly, we have one full byte of data, with the two most-significant80  /// bits set:81  /// 192 is 1100'000082  static_assert(__builtin_bit_cast(bits<2>, (unsigned char)192) == (LITTLE_END ? 0 : 3));83 84 85  /// Here we are instead bitcasting two 1-bits into a destination of 8 bits.86  /// On LE, we should pick the two least-significant bits. On BE, the opposite.87  /// NOTE: Can't verify this with gcc.88  constexpr auto B1 = bits<2>{3};89  static_assert(__builtin_bit_cast(unsigned char, B1) == (LITTLE_END ? 3 : 192));90 91  /// This should be 0000'0110.92  /// On LE, this should result in 6.93  /// On BE, 1100'0000 = 192.94  constexpr auto B2 = bits<3>{6};95  static_assert(__builtin_bit_cast(unsigned char, B2) == (LITTLE_END ? 6 : 192));96 97  constexpr auto B3 = bits<4>{6};98  static_assert(__builtin_bit_cast(unsigned char, B3) == (LITTLE_END ? 6 : 96));99 100  struct B {101    std::byte b0 : 4;102    std::byte b1 : 4;103  };104 105  /// We can properly decompose one byte (8 bit) int two 4-bit bitfields.106  constexpr struct { unsigned char b0; } T = {0xee};107  constexpr B MB = __builtin_bit_cast(B, T);108  static_assert(MB.b0 == 0xe);109  static_assert(MB.b1 == 0xe);110}111 112namespace BitFields {113  struct BitFields {114    unsigned a : 2;115    unsigned b : 30;116  };117 118  constexpr unsigned A = __builtin_bit_cast(unsigned, BitFields{3, 16});119  static_assert(A == (LITTLE_END ? 67 : 3221225488));120 121  struct S {122    unsigned a : 2;123    unsigned b : 28;124    unsigned c : 2;125  };126 127  constexpr S s = __builtin_bit_cast(S, 0xFFFFFFFF);128  static_assert(s.a == 3);129  static_assert(s.b == 268435455);130  static_assert(s.c == 3);131 132  void bitfield_indeterminate() {133    struct BF { unsigned char z : 2; };134    enum byte : unsigned char {};135 136    constexpr BF bf = {0x3};137    static_assert(bit_cast<bits<2>>(bf).bits == bf.z);138    static_assert(bit_cast<unsigned char>(bf));139 140    static_assert(__builtin_bit_cast(byte, bf)); // expected-error {{not an integral constant expression}} \141                                                 // expected-note {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'byte' is invalid}}142 143    struct M {144      // expected-note@+1 {{subobject declared here}}145      unsigned char mem[sizeof(BF)];146    };147    // expected-error@+2 {{initialized by a constant expression}}148    // expected-note@+1 {{not initialized}}149    constexpr M m = bit_cast<M>(bf);150 151    constexpr auto f = []() constexpr {152      // bits<24, unsigned int, LITTLE_END ? 0 : 8> B = {0xc0ffee};153      constexpr struct { unsigned short b1; unsigned char b0;  } B = {0xc0ff, 0xee};154      return bit_cast<bytes<4>>(B);155    };156 157    static_assert(f()[0] + f()[1] + f()[2] == 0xc0 + 0xff + 0xee);158    {159      // expected-error@+2 {{initialized by a constant expression}}160      // expected-note@+1 {{in call to}}161      constexpr auto _bad = f()[3];162    }163 164    struct B {165      unsigned short s0 : 8;166      unsigned short s1 : 8;167      std::byte b0 : 4;168      std::byte b1 : 4;169      std::byte b2 : 4;170    };171    constexpr auto g = [f]() constexpr {172      return bit_cast<B>(f());173    };174    static_assert(g().s0 + g().s1 + g().b0 + g().b1 == 0xc0 + 0xff + 0xe + 0xe);175    {176      // expected-error@+2 {{initialized by a constant expression}}177      // expected-note@+1 {{read of uninitialized object is not allowed in a constant expression}}178      constexpr auto _bad = g().b2;179    }180  }181}182 183namespace BoolVectors {184  typedef bool bool32 __attribute__((ext_vector_type(32)));185  constexpr auto v = bit_cast<bool32>(0xa1c0ffee);186#if LITTLE_END187  static_assert(!v[0]);188  static_assert(v[1]);189  static_assert(v[2]);190  static_assert(v[3]);191  static_assert(!v[4]);192  static_assert(v[5]);193  static_assert(v[6]);194  static_assert(v[7]);195 196  static_assert(v[8]);197  static_assert(v[9]);198  static_assert(v[10]);199  static_assert(v[11]);200  static_assert(v[12]);201  static_assert(v[13]);202  static_assert(v[14]);203  static_assert(v[15]);204 205  static_assert(!v[16]);206  static_assert(!v[17]);207  static_assert(!v[18]);208  static_assert(!v[19]);209  static_assert(!v[20]);210  static_assert(!v[21]);211  static_assert(v[22]);212  static_assert(v[23]);213 214  static_assert(v[24]);215  static_assert(!v[25]);216  static_assert(!v[26]);217  static_assert(!v[27]);218  static_assert(!v[28]);219  static_assert(v[29]);220  static_assert(!v[30]);221  static_assert(v[31]);222 223#else224  static_assert(v[0]);225  static_assert(!v[1]);226  static_assert(v[2]);227  static_assert(!v[3]);228  static_assert(!v[4]);229  static_assert(!v[5]);230  static_assert(!v[6]);231  static_assert(v[7]);232 233  static_assert(v[8]);234  static_assert(v[9]);235  static_assert(!v[10]);236  static_assert(!v[11]);237  static_assert(!v[12]);238  static_assert(!v[13]);239  static_assert(!v[14]);240  static_assert(!v[15]);241 242  static_assert(v[16]);243  static_assert(v[17]);244  static_assert(v[18]);245  static_assert(v[19]);246  static_assert(v[20]);247  static_assert(v[21]);248  static_assert(v[22]);249  static_assert(v[23]);250 251  static_assert(v[24]);252  static_assert(v[25]);253  static_assert(v[26]);254  static_assert(!v[27]);255  static_assert(v[28]);256  static_assert(v[29]);257  static_assert(v[30]);258  static_assert(!v[31]);259#endif260 261  struct pad {262    unsigned short s;263    unsigned char c;264  };265 266  constexpr auto p = bit_cast<pad>(v);267  static_assert(p.s == (LITTLE_END ? 0xffee : 0xa1c0));268  static_assert(p.c == (LITTLE_END ? 0xc0 : 0xff));269}270 271namespace TwoShorts {272  struct B {273    unsigned short s0 : 8;274    unsigned short s1 : 8;275  };276  constexpr struct { unsigned short b1;} T = {0xc0ff};277  constexpr B MB = __builtin_bit_cast(B, T);278#if LITTLE_END279    static_assert(MB.s0 == 0xff);280    static_assert(MB.s1 == 0xc0);281#else282    static_assert(MB.s0 == 0xc0);283    static_assert(MB.s1 == 0xff);284 285#endif286}287 288typedef bool bool8 __attribute__((ext_vector_type(8)));289typedef bool bool9 __attribute__((ext_vector_type(9)));290typedef bool bool16 __attribute__((ext_vector_type(16)));291typedef bool bool17 __attribute__((ext_vector_type(17)));292typedef bool bool32 __attribute__((ext_vector_type(32)));293typedef bool bool128 __attribute__((ext_vector_type(128)));294 295static_assert(bit_cast<unsigned char>(bool8{1,0,1,0,1,0,1,0}) == (LITTLE_END ? 0x55 : 0xAA), "");296constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{'__builtin_bit_cast' source type 'int' does not match destination type 'bool8' (vector of 8 'bool' values) (4 vs 1 bytes)}}297static_assert(check_round_trip<bool8>(static_cast<unsigned char>(0)), "");298static_assert(check_round_trip<bool8>(static_cast<unsigned char>(1)), "");299static_assert(check_round_trip<bool8>(static_cast<unsigned char>(0x55)), "");300 301static_assert(bit_cast<unsigned short>(bool16{1,1,1,1,1,0,0,0, 1,1,1,1,0,1,0,0}) == (LITTLE_END ? 0x2F1F : 0xF8F4), "");302 303static_assert(check_round_trip<bool16>(static_cast<short>(0xCAFE)), "");304static_assert(check_round_trip<bool32>(static_cast<int>(0xCAFEBABE)), "");305 306#ifdef __SIZEOF_INT128__307static_assert(check_round_trip<bool128>(static_cast<__int128_t>(0xCAFEBABE0C05FEFEULL)), "");308#endif309 310static_assert(bit_cast<bits<8, uint16_t, 7>, uint16_t>(0xcafe) == (LITTLE_END ? 0x95 : 0x7f));311static_assert(bit_cast<bits<4, uint16_t, 10>, uint16_t>(0xcafe) == (LITTLE_END ? 0x2 : 0xf));312static_assert(bit_cast<bits<4, uint32_t, 19>, uint32_t>(0xa1cafe) == (LITTLE_END ? 0x4 : 0x5));313 314struct S {315  // little endian:316  //    MSB .... .... LSB317  //        |y|   |x|318  //319  // big endian320  //    MSB .... .... LSB321  //        |x|   |y|322 323  unsigned char x : 4;324  unsigned char y : 4;325 326  constexpr bool operator==(S const &other) const {327    return x == other.x && y == other.y;328  }329};330 331constexpr S s{0xa, 0xb};332static_assert(bit_cast<bits<8>>(s) == (LITTLE_END ? 0xba : 0xab));333static_assert(bit_cast<bits<7>>(s) == (LITTLE_END334                                            ? 0xba & 0x7f335                                            : (0xab & 0xfe) >> 1));336 337static_assert(round_trip<bits<8>>(s) == s);338 339struct R {340  unsigned int r : 31;341  unsigned int : 0;342  unsigned int : 32;343  constexpr bool operator==(R const &other) const {344    return r == other.r;345  }346 };347using T = bits<31, signed long long>;348constexpr R r{0x4ac0ffee};349constexpr T t = bit_cast<T>(r);350static_assert(t == ((0xFFFFFFFF8 << 28) | 0x4ac0ffee)); // sign extension351 352static_assert(round_trip<T>(r) == r);353static_assert(round_trip<R>(t) == t);354 355 356/// The oversized bitfield is an error on Windows and not just a warning.357#if !defined(_WIN32)358struct U {359  // expected-warning@+1 {{exceeds the width of its type}}360  uint32_t trunc : 33;361  uint32_t u : 31;362  constexpr bool operator==(U const &other) const {363    return trunc == other.trunc && u == other.u;364  }365};366struct V {367  uint64_t notrunc : 32;368  uint64_t : 1;369  uint64_t v : 31;370  constexpr bool operator==(V const &other) const {371    return notrunc == other.notrunc && v == other.v;372  }373};374 375constexpr U u{static_cast<unsigned int>(~0), 0x4ac0ffee};376constexpr V v = bit_cast<V>(u);377static_assert(v.v == 0x4ac0ffee);378 379static_assert(round_trip<V>(u) == u);380static_assert(round_trip<U>(v) == v);381 382constexpr auto w = bit_cast<bits<12, unsigned long, 33>>(u);383static_assert(w == (LITTLE_END384                    ? 0x4ac0ffee & 0xFFF385                    : (0x4ac0ffee & (0xFFF << (31 - 12))) >> (31-12)386                  ));387#endif388 389 390namespace NestedStructures {391  struct J {392    struct {393      uint16_t  k : 12;394    } K;395    struct {396      uint16_t  l : 4;397    } L;398  };399 400  static_assert(sizeof(J) == 4);401  constexpr J j = bit_cast<J>(0x8c0ffee5);402 403  static_assert(j.K.k == (LITTLE_END ? 0xee5 : 0x8c0));404  static_assert(j.L.l == 0xf /* yay symmetry */);405  static_assert(bit_cast<bits<4, uint16_t, 16>>(j) == 0xf);406  struct N {407    bits<12, uint16_t> k;408    uint16_t : 16;409  };410  static_assert(bit_cast<N>(j).k == j.K.k);411 412  struct M {413    bits<4, uint16_t, 0> m[2];414    constexpr bool operator==(const M& rhs) const {415      return m[0] == rhs.m[0] && m[1] == rhs.m[1];416    };417  };418  #if LITTLE_END == 1419  constexpr uint16_t want[2] = {0x5, 0xf};420  #else421  constexpr uint16_t want[2] = {0x8000, 0xf000};422  #endif423 424  static_assert(bit_cast<M>(j) == bit_cast<M>(want));425}426 427namespace Enums {428  // ensure we're packed into the top 2 bits429  constexpr int pad = LITTLE_END ? 6 : 0;430  struct X431  {432    char : pad;433    enum class direction: char { left, right, up, down } direction : 2;434  };435 436  constexpr X x = { X::direction::down };437  static_assert(bit_cast<bits<2, signed char, pad>>(x) == -1);438  static_assert(bit_cast<bits<2, unsigned char, pad>>(x) == 3);439  static_assert(440    bit_cast<X>((unsigned char)0x40).direction == X::direction::right);441}442 443namespace IndeterminateBits {444  struct S {445    unsigned a : 13;446    unsigned   : 17;447    unsigned b : 2;448  };449  constexpr unsigned A = __builtin_bit_cast(unsigned, S{12, 3}); // expected-error {{must be initialized by a constant expression}} \450                                                                 // expected-note {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'unsigned int' is invalid}}451 452 453  /// GCC refuses to compile this as soon as we access the indeterminate bits454  /// in the static_assert. MSVC accepts it.455  struct S2 {456    unsigned char a : 2;457  };458  constexpr unsigned char B = __builtin_bit_cast(unsigned char, S2{3});459  static_assert(B == (LITTLE_END ? 3 : 192));460 461 462 463  struct S3 {464    unsigned a : 13;465    unsigned   : 17;466    unsigned b : 2;467  };468 469  struct D {470    unsigned a;471  };472  constexpr D s = __builtin_bit_cast(D, S3{12, 3}); // expected-error {{must be initialized by a constant expression}} \473                                                    // expected-note {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'unsigned int' is invalid}}474 475}476