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