Skip to content

Commit 2fd5fc4

Browse files
committed
add test for review discussion
1 parent f281d34 commit 2fd5fc4

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// RUN: %clang_cc1 -std=c++2a -verify %s
2+
3+
struct A {
4+
int a, b[3], c;
5+
bool operator==(const A&) const = default;
6+
};
7+
8+
constexpr auto a0 = A{0, 0, 3, 4, 5};
9+
10+
// expected-note@+1 {{evaluates to '{0, {0, 3, 4}, 5} == {1, {2, 3, 4}, 5}'}}
11+
static_assert(a0 == A{1, {2, 3, 4}, 5}); // expected-error {{failed}}
12+
13+
struct _arr {
14+
const int b[3];
15+
constexpr bool operator==(const int rhs[3]) const {
16+
for (unsigned i = 0; i < sizeof(b) / sizeof(int); i++)
17+
if (b[i] != rhs[i])
18+
return false;
19+
return true;
20+
}
21+
};
22+
23+
// TODO[seth] syntactically sort of valid but almost entirely unusuable
24+
// (it's an int *, not an int [3] )
25+
// constexpr int _[3] = {...}; would work, but that's not piecewise substitutable
26+
// maybe it's ok? I mean, not like we can do better really...
27+
constexpr auto _ = (int[3]){2, 3, 4};
28+
29+
// output: '{{2, 3, 4}} == {0, 3, 4}' (the `{{` breaks VerifyDiagnosticConsumer::ParseDirective)
30+
// expected-note@+1 {{evaluates to}}
31+
static_assert(_arr{2, 3, 4} == a0.b); // expected-error {{failed}}
32+
33+
struct B {
34+
int a, c; // named the same just to keep things fresh
35+
bool operator==(const B&) const = default;
36+
};
37+
38+
// expected-note@+1 {{evaluates to '{7, 6} == {8, 6}'}}
39+
static_assert(B{7, 6} == B{8, 6}); // expected-error {{failed}}
40+
41+
typedef int v4si __attribute__((__vector_size__(16)));
42+
43+
struct C: A, B {
44+
enum { E1, E2 } e;
45+
bool operator==(const C&) const = default;
46+
};
47+
48+
constexpr auto cc = C{A{1, {2, 3, 4}, 5}, B{7, 6}, C::E1};
49+
50+
// actually '{{1, {2, 3, 4}, 5}, {7, 6}, 0} == {{0, {0, 3, 4}, 5}, {5, 0}, 1}' (the `{{` breaks VerifyDiagnosticConsumer::ParseDirective)
51+
// expected-note@+1 {{evaluates to}}
52+
static_assert(cc == C{a0, {5}, C::E2}); // expected-error {{failed}}
53+
54+
// this little guy? oh, I wouldn't worry about this little guy
55+
namespace std {
56+
template <class To, class From>
57+
constexpr To bit_cast(const From &from) {
58+
static_assert(sizeof(To) == sizeof(From));
59+
return __builtin_bit_cast(To, from);
60+
}
61+
} // namespace std
62+
63+
typedef int v4si __attribute__((__vector_size__(16)));
64+
65+
struct V {
66+
v4si v;
67+
68+
// doesn't work
69+
// vectors are not contextually convertable to `bool`, and
70+
// `==` on vectors produces a vector of element-wise results
71+
// bool operator==(const V&) const = default;
72+
73+
constexpr bool operator==(const V& rhs) const {
74+
// doesn't work
75+
// __builtin_reduce_and is not valid in a constant expression
76+
// return __builtin_reduce_and(b == rhs.b) && __builtin_reduce_and(v == rhs.v);
77+
78+
// also doesn't work
79+
// surprisingly, b[0] is also not valid in a constant expression (nor v[0])
80+
// return b[0] == rhs.b[0] && ...
81+
82+
struct cmp {
83+
unsigned char v [sizeof(v4si)];
84+
bool operator==(const cmp&) const = default;
85+
};
86+
return std::bit_cast<cmp>(v) == std::bit_cast<cmp>(rhs.v);
87+
};
88+
89+
};
90+
// todo[seth] do I cause infinite evaluator recursion if I move this up into the function above?
91+
static_assert(V{1, 2, 3, 4} == V{1, 2, 3, 4});
92+
93+
// '{{1, 2, 3, 4}} == {{1, 2, 0, 4}}'
94+
// expected-note@+1 {{evaluates to}}
95+
static_assert(V{1, 2, 3, 4} == V{1, 2, 0, 4}); // expected-error {{failed}}
96+
97+
constexpr auto v = (v4si){1, 2, 3, 4};
98+
constexpr auto vv = V{{1, 2, 3, 4}};
99+
100+
101+
// there appears to be no constexpr-compatible way to write an == for
102+
// two `bool4`s at this time, since std::bit_cast doesn't support it
103+
// typedef bool bool4 __attribute__((ext_vector_type(4)));
104+
105+
// so we use a bool8
106+
typedef bool bool8 __attribute__((ext_vector_type(8)));
107+
108+
struct BV {
109+
bool8 b;
110+
constexpr bool operator==(const BV& rhs) const {
111+
return std::bit_cast<unsigned char>(b) == std::bit_cast<unsigned char>(rhs.b);
112+
}
113+
};
114+
115+
// '{{false, true, false, false, false, false, false, false}} == {{true, false, false, false, false, false, false, false}}'
116+
// expected-note@+1 {{evaluates to}}
117+
static_assert(BV{{0, 1}} == BV{{1, 0}}); // expected-error {{failed}}

0 commit comments

Comments
 (0)