1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14
10 
11 // type_traits
12 
13 // has_unique_object_representations
14 
15 #include <type_traits>
16 
17 template <bool ExpectedValue, class T>
test()18 void test() {
19   static_assert(std::has_unique_object_representations<T>::value == ExpectedValue);
20   static_assert(std::has_unique_object_representations<const T>::value == ExpectedValue);
21   static_assert(std::has_unique_object_representations<volatile T>::value == ExpectedValue);
22   static_assert(std::has_unique_object_representations<const volatile T>::value == ExpectedValue);
23 
24   static_assert(std::has_unique_object_representations_v<T> == ExpectedValue);
25   static_assert(std::has_unique_object_representations_v<const T> == ExpectedValue);
26   static_assert(std::has_unique_object_representations_v<volatile T> == ExpectedValue);
27   static_assert(std::has_unique_object_representations_v<const volatile T> == ExpectedValue);
28 }
29 
30 class Empty {};
31 
32 union EmptyUnion {};
33 
34 struct NonEmptyUnion {
35   int x;
36   unsigned y;
37 };
38 
39 struct ZeroWidthBitfield {
40   int : 0;
41 };
42 
43 class Virtual {
44   virtual ~Virtual();
45 };
46 
47 class Abstract {
48   virtual ~Abstract() = 0;
49 };
50 
51 struct UnsignedInt {
52   unsigned foo;
53 };
54 
55 struct WithoutPadding {
56   int x;
57   int y;
58 };
59 
60 struct WithPadding {
61   char bar;
62   int foo;
63 };
64 
65 template <int>
66 class NTTP_ClassType_WithoutPadding {
67   int x;
68 };
69 
test()70 void test() {
71   test<false, void>();
72   test<false, Empty>();
73   test<false, EmptyUnion>();
74   test<false, Virtual>();
75   test<false, ZeroWidthBitfield>();
76   test<false, Abstract>();
77   test<false, WithPadding>();
78   test<false, WithPadding[]>();
79   test<false, WithPadding[][3]>();
80 
81   // I would also expect that there are systems where they do not.
82   // I would expect all three of these to have unique representations.
83   //   test<false, int&>();
84   //   test<false, int *>();
85   //   test<false, double>();
86 
87   test<true, unsigned>();
88   test<true, UnsignedInt>();
89   test<true, WithoutPadding>();
90   test<true, NonEmptyUnion>();
91   test<true, char[3]>();
92   test<true, char[3][4]>();
93   test<true, char[3][4][5]>();
94   test<true, char[]>();
95   test<true, char[][2]>();
96   test<true, char[][2][3]>();
97 
98   // Important test case for https://github.com/llvm/llvm-project/issues/95311.
99   // Note that the order is important here, we want to instantiate the array
100   // variants before the non-array ones, otherwise we don't trigger the bug.
101   {
102     test<true, NTTP_ClassType_WithoutPadding<0>[]>();
103     test<true, NTTP_ClassType_WithoutPadding<0>[][3]>();
104     test<true, NTTP_ClassType_WithoutPadding<0>>();
105   }
106 }
107