blob: b8e8e73dfafa3062e21254f4a0d192fd8db091ad (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
// P0847R7
// { dg-do run { target c++23 } }
// conversion of the implicit object argument to an xobj parameter
// using a user defined conversion or converting constructor
// when calling by value xobj member functions
// see explicit-obj-by-value1.C for details on this test
using uintptr_t = __UINTPTR_TYPE__;
inline constexpr uintptr_t magic = 42;
struct S;
struct FromS {
uintptr_t _v;
FromS(S);
};
struct S {
operator uintptr_t() const {
return magic;
}
uintptr_t f(this uintptr_t n) {
return n;
}
uintptr_t g(this FromS from_s) {
return from_s._v;
}
};
FromS::FromS(S) : _v(magic) {}
int main()
{
S s0{};
S s1{};
// prevent (absurdly improbable) bogus failures
S& s = magic != (uintptr_t)(&s0) ? s0 : s1;
uintptr_t const ret0 = s.f();
// check for reinterpretation of the object argument
if (ret0 == (uintptr_t)(&s))
__builtin_abort ();
// check for a bugged conversion
if (ret0 != magic)
__builtin_abort ();
uintptr_t const ret1 = s.g();
// check for reinterpretation of the object argument
if (ret1 == (uintptr_t)(&s))
__builtin_abort ();
// check for a bugged conversion
if (ret1 != magic)
__builtin_abort ();
}
|