Skip to content

Commit e1017d0

Browse files
committed
Add tests for CWG issues 6, 212, 232, 2823.
Unfortunately this adds two more "no"s to cxx_dr_status.
1 parent 4c6a38c commit e1017d0

File tree

5 files changed

+335
-32
lines changed

5 files changed

+335
-32
lines changed

clang/test/CXX/drs/cwg0xx.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,24 @@ namespace cwg5 { // cwg5: 3.1
9090
const C c = e;
9191
} // namespace cwg5
9292

93+
namespace cwg6 { // cwg6 codegen is tested in cwg6.cpp
94+
#if __cplusplus >= 201103L
95+
struct Counter {
96+
int copies;
97+
constexpr Counter(int copies) : copies(copies) {}
98+
constexpr Counter(const Counter& other) : copies(other.copies + 1) {}
99+
};
100+
101+
// Passing an lvalue by value makes a non-elidable copy.
102+
constexpr int PassByValue(Counter c) { return c.copies; }
103+
constexpr int PassByValue2(Counter c) { return PassByValue(c); }
104+
constexpr int PassByValue3(Counter c) { return PassByValue2(c); }
105+
static_assert(PassByValue(Counter(0)) == 0, "expect no copies");
106+
static_assert(PassByValue2(Counter(0)) == 1, "expect 1 copy");
107+
static_assert(PassByValue3(Counter(0)) == 2, "expect 2 copies");
108+
#endif
109+
} // namespace cwg6
110+
93111
namespace cwg7 { // cwg7: 3.4
94112
class A { public: ~A(); };
95113
class B : virtual private A {}; // #cwg7-B

clang/test/CXX/drs/cwg28xx.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,22 @@ namespace cwg2819 { // cwg2819: 19 c++26
6161
#endif
6262
} // namespace cwg2819
6363

64+
namespace cwg2823 { // cwg2823: no
65+
#if __cplusplus >= 201103L
66+
constexpr int *p = 0;
67+
constexpr int *q1 = &*p; // expected-error {{constant expression}} expected-note {{dereferencing a null pointer}}
68+
// FIXME: invalid: dereferencing a null pointer.
69+
constexpr int *q2 = &p[0];
70+
71+
int arr[32];
72+
constexpr int *r = arr;
73+
// FIXME: invalid: dereferencing a past-the-end pointer.
74+
constexpr int *s1 = &*(r + 32);
75+
// FIXME: invalid: dereferencing a past-the-end pointer.
76+
constexpr int *s2 = &r[32];
77+
#endif
78+
}
79+
6480
namespace cwg2847 { // cwg2847: 19 review 2024-03-01
6581

6682
#if __cplusplus >= 202002L

clang/test/CXX/drs/cwg2xx.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,37 @@ namespace cwg211 { // cwg211: 2.7
230230
};
231231
} // namespace cwg211
232232

233+
namespace cwg212 { // cwg212: yes
234+
template<typename T> struct Base;
235+
template<typename T> struct Derived;
236+
237+
int *overload(void*);
238+
float *overload(Base<int>*);
239+
double *overload(Base<long>*);
240+
241+
void f(Derived<int> *p) {
242+
// OK, calls void* overload.
243+
int *a = overload(p);
244+
245+
Base<int> *q = p; // expected-error {{cannot initialize}}
246+
}
247+
248+
template<typename T> struct Base {};
249+
template<typename T> struct Derived : Base<T> {};
250+
251+
void g(Derived<long> *p) {
252+
// OK, instantiates and calls Base<long>* overlod.
253+
double *b = overload(p);
254+
(void)b;
255+
}
256+
257+
void h(Derived<float> *p) {
258+
// OK, instantiates and converts.
259+
Base<float> *q = p;
260+
(void)q;
261+
}
262+
}
263+
233264
namespace cwg213 { // cwg213: 2.7
234265
template <class T> struct A : T {
235266
void h(T t) {
@@ -593,6 +624,9 @@ namespace cwg231 { // cwg231: 2.7
593624
}
594625
} // namespace cwg231
595626

627+
// 232 is NAD; the desired behavior is described in 2823.
628+
// cwg232: dup 2823
629+
596630
// cwg234: na
597631
// cwg235: na
598632

clang/test/CXX/drs/cwg6.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %clang_cc1 -std=c++98 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | FileCheck %s --check-prefixes CHECK
2+
// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | FileCheck %s --check-prefixes CHECK
3+
// RUN: %clang_cc1 -std=c++14 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | FileCheck %s --check-prefixes CHECK
4+
// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | FileCheck %s --check-prefixes CHECK
5+
// RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | FileCheck %s --check-prefixes CHECK
6+
// RUN: %clang_cc1 -std=c++23 %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | FileCheck %s --check-prefixes CHECK
7+
// RUN: %clang_cc1 -std=c++2c %s -triple x86_64-linux-gnu -emit-llvm -o - -fexceptions -fcxx-exceptions -pedantic-errors | FileCheck %s --check-prefixes CHECK
8+
9+
namespace cwg6 { // cwg6: yes
10+
11+
struct A {
12+
A();
13+
A(const A&);
14+
~A();
15+
};
16+
17+
inline void f(A a) {}
18+
19+
// CHECK-LABEL: define {{.*}} @_ZN4cwg64callEv
20+
void call() {
21+
A a;
22+
// We copy the parameter here, even though object is not mutated by f and
23+
// otherwise satisfies the criteria for the proposed CWG6 optimization.
24+
// CHECK: {{call|invoke}} {{.*}} @_ZN4cwg61AC1ERKS0_
25+
// CHECK: {{call|invoke}} {{.*}} @_ZN4cwg61fE
26+
f(a);
27+
// CHECK: {{call|invoke}} {{.*}} @_ZN4cwg61AD1Ev
28+
// CHECK: {{call|invoke}} {{.*}} @_ZN4cwg61AD1Ev
29+
}
30+
31+
} // namespace cwg6

0 commit comments

Comments
 (0)