Skip to content

Commit bca2bfe

Browse files
committed
[clang] Add test for CWG203 "Type of address-of-member expression"
1 parent c56b743 commit bca2bfe

File tree

2 files changed

+137
-3
lines changed

2 files changed

+137
-3
lines changed

clang/test/CXX/drs/cwg2xx.cpp

Lines changed: 136 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
// RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11,cxx98-11,cxx98-14,cxx98-17 -fexceptions -fcxx-exceptions -pedantic-errors
33
// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11,since-cxx14,cxx98-14,cxx98-17 -fexceptions -fcxx-exceptions -pedantic-errors
44
// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,cxx98-17 -fexceptions -fcxx-exceptions -pedantic-errors
5-
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
6-
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
5+
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
6+
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
7+
// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
78

89
// FIXME: diagnostic above is emitted only on Windows platforms
910
// PR13819 -- __SIZE_TYPE__ is incompatible.
@@ -41,6 +42,139 @@ namespace cwg202 { // cwg202: 3.1
4142
template struct X<f>;
4243
}
4344

45+
namespace cwg203 { // cwg203: 2.8
46+
namespace ex1 {
47+
struct B {
48+
int i;
49+
};
50+
struct D1 : B {};
51+
struct D2 : B {};
52+
53+
int(D1::*pmD1) = &D2::i;
54+
} // namespace ex1
55+
56+
#if __cplusplus >= 202002L
57+
namespace ex2 {
58+
struct A {
59+
int i;
60+
virtual void f() = 0; // #cwg203-ex2-A-f
61+
};
62+
63+
struct B : A {
64+
int j;
65+
constexpr B() : j(5) {}
66+
virtual void f();
67+
};
68+
69+
struct C : B {
70+
constexpr C() { j = 10; }
71+
};
72+
73+
template <class T>
74+
constexpr int DefaultValue(int(T::*m)) {
75+
return T().*m;
76+
// since-cxx20-error@-1 {{allocating an object of abstract class type 'cwg203::ex2::A'}}
77+
// since-cxx20-note@#cwg203-ex2-a {{in instantiation of function template specialization 'cwg203::ex2::DefaultValue<cwg203::ex2::A>' requested here}}
78+
// since-cxx20-note@#cwg203-ex2-A-f {{unimplemented pure virtual method 'f' in 'A'}}
79+
} // #cwg203-ex2-DefaultValue
80+
81+
int a = DefaultValue(&B::i); // #cwg203-ex2-a
82+
static_assert(DefaultValue(&C::j) == 5, "");
83+
} // namespace ex2
84+
#endif
85+
86+
namespace ex3 {
87+
class Base {
88+
public:
89+
int func() const;
90+
};
91+
92+
class Derived : public Base {};
93+
94+
template <class T> class Templ { // #cwg203-ex3-Templ
95+
public:
96+
template <class S> Templ(S (T::*ptmf)() const); // #cwg203-ex3-Templ-ctor
97+
};
98+
99+
void foo() { Templ<Derived> x(&Derived::func); }
100+
// expected-error@-1 {{<source>:46:29: error: no matching constructor for initialization of 'Templ<Derived>'}}
101+
// expected-note@#cwg203-ex3-Templ {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int (cwg203::ex3::Base::*)() const' to 'const Templ<Derived>' for 1st argument}}
102+
// expected-note@#cwg203-ex3-Templ {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int (cwg203::ex3::Base::*)() const' to 'Templ<Derived>' for 1st argument}}
103+
// expected-note@#cwg203-ex3-Templ-ctor {{candidate template ignored: could not match 'cwg203::ex3::Derived' against 'cwg203::ex3::Base'}}
104+
} // namespace ex3
105+
106+
namespace ex4 {
107+
struct Very_base {
108+
int a;
109+
};
110+
struct Base1 : Very_base {};
111+
struct Base2 : Very_base {};
112+
struct Derived : Base1, Base2 {
113+
};
114+
115+
int f() {
116+
Derived d;
117+
int Derived::*a_ptr = &Derived::Base1::a;
118+
/* expected-error@-1
119+
{{ambiguous conversion from pointer to member of base class 'cwg203::ex4::Very_base' to pointer to member of derived class 'cwg203::ex4::Derived':
120+
struct cwg203::ex4::Derived -> Base1 -> Very_base
121+
struct cwg203::ex4::Derived -> Base2 -> Very_base}}*/
122+
};
123+
} // namespace ex4
124+
125+
namespace ex5 {
126+
struct Base {
127+
int a;
128+
};
129+
struct Derived : Base {
130+
int b;
131+
};
132+
133+
template <typename Class, typename Member_type, Member_type Base::*ptr>
134+
Member_type get(Class &c) {
135+
return c.*ptr;
136+
}
137+
138+
void call(int (*f)(Derived &)); // #cwg203-ex5-call
139+
140+
int main() {
141+
// ill-formed, contrary to Core issue filing:
142+
// `&Derived::b` yields `int Derived::*`, which can't initialize NTTP of type `int Base::*`,
143+
// because (implicit) pointer-to-member conversion doesn't upcast.
144+
call(&get<Derived, int, &Derived::b>);
145+
// expected-error@-1 {{no matching function for call to 'call'}}
146+
// expected-note@#cwg203-ex5-call {{candidate function not viable: no overload of 'get' matching 'int (*)(Derived &)' for 1st argument}}
147+
148+
// well-formed, contrary to Core issue filing:
149+
// `&Derived::a` yields `int Base::*`,
150+
// which can initialize NTTP of type `int Base::*`.
151+
call(&get<Derived, int, &Derived::a>);
152+
153+
call(&get<Base, int, &Derived::a>);
154+
// expected-error@-1 {{no matching function for call to 'call'}}
155+
// expected-note@#cwg203-ex5-call {{candidate function not viable: no overload of 'get' matching 'int (*)(Derived &)' for 1st argument}}
156+
}
157+
} // namespace ex5
158+
159+
namespace ex6 {
160+
struct Base {
161+
int a;
162+
};
163+
struct Derived : private Base { // #cwg203-ex6-Derived
164+
public:
165+
using Base::a; // make `a` accessible
166+
};
167+
168+
int main() {
169+
Derived d;
170+
int b = d.a;
171+
int Derived::*ptr = &Derived::a;
172+
// expected-error@-1 {{cannot cast private base class 'cwg203::ex6::Base' to 'cwg203::ex6::Derived'}}
173+
// expected-note@#cwg203-ex6-Derived {{declared private here}}
174+
}
175+
} // namespace ex6
176+
} // namespace cwg203
177+
44178
// cwg204: sup 820
45179

46180
namespace cwg206 { // cwg206: yes

clang/www/cxx_dr_status.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1263,7 +1263,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
12631263
<td><a href="https://cplusplus.github.io/CWG/issues/203.html">203</a></td>
12641264
<td>NAD</td>
12651265
<td>Type of address-of-member expression</td>
1266-
<td class="unknown" align="center">Unknown</td>
1266+
<td class="full" align="center">Clang 2.8</td>
12671267
</tr>
12681268
<tr id="204">
12691269
<td><a href="https://cplusplus.github.io/CWG/issues/204.html">204</a></td>

0 commit comments

Comments
 (0)