Skip to content

Commit 1e3a1ce

Browse files
zygoloidEndilll
andauthored
Add tests for CWG issues 6, 212, 232, 2823. (#165633)
Unfortunately this adds two more "no"s to cxx_dr_status for 232 and 2823. --------- Co-authored-by: Vlad Serebrennikov <serebrennikov.vladislav@gmail.com>
1 parent b2d12d6 commit 1e3a1ce

File tree

5 files changed

+110
-4
lines changed

5 files changed

+110
-4
lines changed

clang/test/CXX/drs/cwg0xx.cpp

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

93+
// cwg6 is in cwg6.cpp
94+
9395
namespace cwg7 { // cwg7: 3.4
9496
class A { public: ~A(); };
9597
class B : virtual private A {}; // #cwg7-B

clang/test/CXX/drs/cwg28xx.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,24 @@ 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;
68+
// expected-error@-1 {{constexpr variable 'q1' must be initialized by a constant expression}}
69+
// expected-note@-2 {{dereferencing a null pointer is not allowed in a constant expression}}
70+
// FIXME: invalid: dereferencing a null pointer.
71+
constexpr int *q2 = &p[0];
72+
73+
int arr[32];
74+
constexpr int *r = arr;
75+
// FIXME: invalid: dereferencing a past-the-end pointer.
76+
constexpr int *s1 = &*(r + 32);
77+
// FIXME: invalid: dereferencing a past-the-end pointer.
78+
constexpr int *s2 = &r[32];
79+
#endif
80+
}
81+
6482
namespace cwg2847 { // cwg2847: 19 review 2024-03-01
6583

6684
#if __cplusplus >= 202002L

clang/test/CXX/drs/cwg2xx.cpp

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

233+
namespace cwg212 { // cwg212: 2.7
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;
246+
// expected-error@-1 {{cannot initialize a variable of type 'Base<int> *' with an lvalue of type 'Derived<int> *'}}
247+
}
248+
249+
template<typename T> struct Base {};
250+
template<typename T> struct Derived : Base<T> {};
251+
252+
void g(Derived<long> *p) {
253+
// OK, instantiates and calls Base<long>* overlod.
254+
double *b = overload(p);
255+
(void)b;
256+
}
257+
258+
void h(Derived<float> *p) {
259+
// OK, instantiates and converts.
260+
Base<float> *q = p;
261+
(void)q;
262+
}
263+
}
264+
233265
namespace cwg213 { // cwg213: 2.7
234266
template <class T> struct A : T {
235267
void h(T t) {
@@ -593,6 +625,9 @@ namespace cwg231 { // cwg231: 2.7
593625
}
594626
} // namespace cwg231
595627

628+
// 232 is NAD; the desired behavior is described in 2823.
629+
// cwg232: dup 2823
630+
596631
// cwg234: na
597632
// cwg235: na
598633

clang/test/CXX/drs/cwg6.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
#if __cplusplus == 199711L
10+
#define static_assert(expr) __extension__ _Static_assert(expr)
11+
#define noexcept throw()
12+
#endif
13+
14+
namespace cwg6 { // cwg6: 2.7
15+
#if __cplusplus >= 201103L
16+
struct Counter {
17+
int copies;
18+
constexpr Counter(int copies) : copies(copies) {}
19+
constexpr Counter(const Counter& other) : copies(other.copies + 1) {}
20+
};
21+
22+
// Passing an lvalue by value makes a non-elidable copy.
23+
constexpr int PassByValue(Counter c) { return c.copies; }
24+
constexpr int PassByValue2(Counter c) { return PassByValue(c); }
25+
constexpr int PassByValue3(Counter c) { return PassByValue2(c); }
26+
static_assert(PassByValue(Counter(0)) == 0, "expect no copies");
27+
static_assert(PassByValue2(Counter(0)) == 1, "expect 1 copy");
28+
static_assert(PassByValue3(Counter(0)) == 2, "expect 2 copies");
29+
#endif
30+
31+
struct A {
32+
A() noexcept;
33+
A(const A&) noexcept;
34+
~A() noexcept;
35+
};
36+
37+
inline void f(A a) noexcept {}
38+
39+
// CHECK-LABEL: define {{.*}} @_ZN4cwg64callEv
40+
void call() {
41+
A a;
42+
// We copy the parameter here, even though object is not mutated by f and
43+
// otherwise satisfies the criteria for the proposed CWG6 optimization.
44+
// CHECK: call {{.*}} @_ZN4cwg61AC1ERKS0_(
45+
// CHECK: call {{.*}} @_ZN4cwg61fENS_1AE(
46+
f(a);
47+
// CHECK: call {{.*}} @_ZN4cwg61AD1Ev(
48+
// CHECK: call {{.*}} @_ZN4cwg61AD1Ev(
49+
}
50+
51+
} // namespace cwg6

clang/www/cxx_dr_status.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
8181
<td><a href="https://cplusplus.github.io/CWG/issues/6.html">6</a></td>
8282
<td>NAD</td>
8383
<td>Should the optimization that allows a class object to alias another object also allow the case of a parameter in an inline function to alias its argument?</td>
84-
<td class="unknown" align="center">Unknown</td>
84+
<td class="full" align="center">Yes</td>
8585
</tr>
8686
<tr id="7">
8787
<td><a href="https://cplusplus.github.io/CWG/issues/7.html">7</a></td>
@@ -1318,7 +1318,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
13181318
<td><a href="https://cplusplus.github.io/CWG/issues/212.html">212</a></td>
13191319
<td>CD4</td>
13201320
<td>Implicit instantiation is not described clearly enough</td>
1321-
<td class="unknown" align="center">Unknown</td>
1321+
<td class="full" align="center">Yes</td>
13221322
</tr>
13231323
<tr id="213">
13241324
<td><a href="https://cplusplus.github.io/CWG/issues/213.html">213</a></td>
@@ -1438,7 +1438,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
14381438
<td><a href="https://cplusplus.github.io/CWG/issues/232.html">232</a></td>
14391439
<td>NAD</td>
14401440
<td>Is indirection through a null pointer undefined behavior?</td>
1441-
<td class="unknown" align="center">Unknown</td>
1441+
<td class="none" align="center">Duplicate of <a href="#2823">2823</a></td>
14421442
</tr>
14431443
<tr id="233">
14441444
<td><a href="https://cplusplus.github.io/CWG/issues/233.html">233</a></td>
@@ -16790,7 +16790,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
1679016790
<td><a href="https://cplusplus.github.io/CWG/issues/2823.html">2823</a></td>
1679116791
<td>CD7</td>
1679216792
<td>Implicit undefined behavior when dereferencing pointers</td>
16793-
<td class="unknown" align="center">Unknown</td>
16793+
<td class="none" align="center">No</td>
1679416794
</tr>
1679516795
<tr id="2824">
1679616796
<td><a href="https://cplusplus.github.io/CWG/issues/2824.html">2824</a></td>

0 commit comments

Comments
 (0)