Skip to content

Commit d542eb7

Browse files
authored
[clang] Add tests for CWG issues regarding completeness of types (#92113)
This patch covers the following Core issues: [CWG930](https://cplusplus.github.io/CWG/issues/930.html) "`alignof` with incomplete array type" [CWG1110](https://cplusplus.github.io/CWG/issues/1110.html) "Incomplete return type should be allowed in `decltype` operand" [CWG1340](https://cplusplus.github.io/CWG/issues/1340.html) "Complete type in member pointer expressions" [CWG1352](https://cplusplus.github.io/CWG/issues/1352.html) "Inconsistent class scope and completeness rules" [CWG1458](https://cplusplus.github.io/CWG/issues/1458.html) "Address of incomplete type vs `operator&()`" [CWG1824](https://cplusplus.github.io/CWG/issues/1824.html) "Completeness of return type vs point of instantiation" [CWG1832](https://cplusplus.github.io/CWG/issues/1832.html) "Casting to incomplete enumeration" [CWG2304](https://cplusplus.github.io/CWG/issues/2304.html) "Incomplete type vs overload resolution" [CWG2310](https://cplusplus.github.io/CWG/issues/2310.html) "Type completeness and derived-to-base pointer conversions" [CWG2430](https://cplusplus.github.io/CWG/issues/2430.html) "Completeness of return and parameter types of member functions" [CWG2512](https://cplusplus.github.io/CWG/issues/2512.html) "`typeid` and incomplete class types" [CWG2630](https://cplusplus.github.io/CWG/issues/2630.html) "Syntactic specification of class completeness" [CWG2718](https://cplusplus.github.io/CWG/issues/2718.html) "Type completeness for derived-to-base conversions" [CWG2857](https://cplusplus.github.io/CWG/issues/2857.html) "Argument-dependent lookup with incomplete class types" Current wording for CWG1110 came from [P0135R1](https://wg21.link/p0135R1) "Wording for guaranteed copy elision through simplified value categories". As a drive-by fix, I fixed incorrect status of CWG1815, test for which was added in #87933. CC @yronglin
1 parent 378c9e9 commit d542eb7

13 files changed

+250
-30
lines changed

clang/test/CXX/drs/cwg11xx.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@
44
// RUN: %clang_cc1 -std=c++17 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
55
// RUN: %clang_cc1 -std=c++2a %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
66

7+
namespace cwg1110 { // cwg1110: 3.1
8+
#if __cplusplus >= 201103L
9+
template <typename T>
10+
T return_T();
11+
12+
struct A;
13+
14+
template <typename>
15+
struct B;
16+
17+
decltype(return_T<A>())* a;
18+
decltype(return_T<B<int>>())* b;
19+
#endif
20+
} // namespace cwg1110
21+
722
namespace cwg1111 { // cwg1111: 3.2
823
namespace example1 {
924
template <typename> struct set; // #cwg1111-struct-set

clang/test/CXX/drs/cwg13xx.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,18 @@ namespace cwg1330 { // cwg1330: 4 c++11
306306

307307
// cwg1334: sup 1719
308308

309+
namespace cwg1340 { // cwg1340: 2.9
310+
struct A;
311+
struct B;
312+
313+
void f(B* a, A B::* p) {
314+
(*a).*p;
315+
// expected-warning@-1 {{expression result unused}}
316+
a->*p;
317+
// expected-warning@-1 {{expression result unused}}
318+
}
319+
} // namespace cwg1340
320+
309321
namespace cwg1341 { // cwg1341: sup P0683R1
310322
#if __cplusplus >= 202002L
311323
int a;
@@ -451,6 +463,25 @@ static_assert(!__is_nothrow_constructible(D4, int), "");
451463
#endif
452464
} // namespace cwg1350
453465

466+
namespace cwg1352 { // cwg1352: 3.0
467+
struct A {
468+
#if __cplusplus >= 201103L
469+
int a = sizeof(A);
470+
#endif
471+
void f(int b = sizeof(A));
472+
};
473+
474+
template <typename T>
475+
struct B {
476+
#if __cplusplus >= 201103L
477+
int a = sizeof(B) + sizeof(T);
478+
#endif
479+
void f(int b = sizeof(B) + sizeof(T));
480+
};
481+
482+
template class B<int>;
483+
} // namespace cwg1352
484+
454485
namespace cwg1358 { // cwg1358: 3.1
455486
#if __cplusplus >= 201103L
456487
struct Lit { constexpr operator int() const { return 0; } };

clang/test/CXX/drs/cwg14xx.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,23 @@ struct A {
8686
};
8787
}
8888

89+
namespace cwg1458 { // cwg1458: 3.1
90+
#if __cplusplus >= 201103L
91+
struct A;
92+
93+
void f() {
94+
constexpr A* a = nullptr;
95+
constexpr int p = &*a;
96+
// expected-error@-1 {{cannot initialize a variable of type 'const int' with an rvalue of type 'A *'}}
97+
constexpr A *p2 = &*a;
98+
}
99+
100+
struct A {
101+
int operator&();
102+
};
103+
#endif
104+
} // namespace cwg1458
105+
89106
namespace cwg1460 { // cwg1460: 3.5
90107
#if __cplusplus >= 201103L
91108
namespace DRExample {

clang/test/CXX/drs/cwg18xx.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ namespace cwg1814 { // cwg1814: yes
206206
#endif
207207
}
208208

209-
namespace cwg1815 { // cwg1815: yes
209+
namespace cwg1815 { // cwg1815: 19
210210
#if __cplusplus >= 201402L
211211
struct A { int &&r = 0; };
212212
A a = {};
@@ -303,6 +303,32 @@ namespace cwg1822 { // cwg1822: yes
303303
#endif
304304
}
305305

306+
namespace cwg1824 { // cwg1824: 2.7
307+
template<typename T>
308+
struct A {
309+
T t;
310+
};
311+
312+
struct S {
313+
A<S> f() { return A<S>(); }
314+
};
315+
} // namespace cwg1824
316+
317+
namespace cwg1832 { // cwg1832: 3.0
318+
enum E { // #cwg1832-E
319+
a = static_cast<int>(static_cast<E>(0))
320+
// expected-error@-1 {{'E' is an incomplete type}}
321+
// expected-note@#cwg1832-E {{definition of 'cwg1832::E' is not complete until the closing '}'}}
322+
};
323+
324+
#if __cplusplus >= 201103L
325+
enum E2: decltype(static_cast<E2>(0), 0) {};
326+
// expected-error@-1 {{unknown type name 'E2'}}
327+
enum class E3: decltype(static_cast<E3>(0), 0) {};
328+
// expected-error@-1 {{unknown type name 'E3'}}
329+
#endif
330+
} // namespace cwg1832
331+
306332
namespace cwg1837 { // cwg1837: 3.3
307333
#if __cplusplus >= 201103L
308334
template <typename T>

clang/test/CXX/drs/cwg23xx.cpp

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
2-
// RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
3-
// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
2+
// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
3+
// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx11-14,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
44
// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
55
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
66
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
@@ -47,6 +47,50 @@ void g() {
4747
} // namespace cwg2303
4848
#endif
4949

50+
namespace cwg2304 { // cwg2304: 2.8
51+
template<typename T> void foo(T, int);
52+
template<typename T> void foo(T&, ...);
53+
struct Q; // #cwg2304-Q
54+
void fn1(Q &data_vectors) {
55+
foo(data_vectors, 0);
56+
// expected-error@-1 {{argument type 'cwg2304::Q' is incomplete}}
57+
// expected-note@#cwg2304-Q {{forward declaration of 'cwg2304::Q'}}
58+
}
59+
} // namespace cwg2304
60+
61+
namespace cwg2310 { // cwg2310: partial
62+
#if __cplusplus >= 201103L
63+
template<typename A, typename B>
64+
struct check_derived_from {
65+
static A a;
66+
// FIXME: all 3 examples should be rejected in all language modes.
67+
// FIXME: we should test this in 98 mode.
68+
// FIXME: we accept this when MSVC triple is used
69+
static constexpr B *p = &a;
70+
#if !defined(_WIN32) || defined(__MINGW32__)
71+
// cxx11-14-error@-2 {{cannot initialize a variable of type 'cwg2310::X *const' with an rvalue of type 'cwg2310::Z *'}}
72+
// cxx11-14-note@#cwg2310-X {{in instantiation of template class 'cwg2310::check_derived_from<cwg2310::Z, cwg2310::X>' requested here}}
73+
// cxx11-14-error@-4 {{cannot initialize a variable of type 'cwg2310::Y *const' with an rvalue of type 'cwg2310::Z *'}}
74+
// cxx11-14-note@#cwg2310-Y {{in instantiation of template class 'cwg2310::check_derived_from<cwg2310::Z, cwg2310::Y>' requested here}}
75+
#endif
76+
};
77+
78+
struct W {};
79+
struct X {};
80+
struct Y {};
81+
struct Z : W,
82+
X, check_derived_from<Z, X>, // #cwg2310-X
83+
check_derived_from<Z, Y>, Y // #cwg2310-Y
84+
{
85+
// FIXME: It was properly rejected before, but we're crashing since Clang 11 in C++11 and C++14 modes.
86+
// See https://github.com/llvm/llvm-project/issues/59920
87+
#if __cplusplus >= 201703L
88+
check_derived_from<Z, W> cdf;
89+
#endif
90+
};
91+
#endif
92+
} // namespace cwg2310
93+
5094
// cwg2331: na
5195
// cwg2335 is in cwg2335.cxx
5296

clang/test/CXX/drs/cwg24xx.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ void fallthrough(int n) {
4545
#endif
4646
}
4747

48+
namespace cwg2430 { // cwg2430: 2.7
49+
struct S {
50+
S f(S s) { return s; }
51+
};
52+
} // namespace cwg2430
53+
4854
namespace cwg2450 { // cwg2450: 18
4955
#if __cplusplus >= 202302L
5056
struct S {int a;};

clang/test/CXX/drs/cwg25xx.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,21 @@
66
// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20,since-cxx23 -fexceptions -fcxx-exceptions -pedantic-errors
77
// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20,since-cxx23 -fexceptions -fcxx-exceptions -pedantic-errors
88

9-
#if __cplusplus == 199711L
10-
// expected-no-diagnostics
11-
#endif
9+
namespace std {
10+
struct type_info{};
11+
} // namespace std
1212

1313
// cwg2504 is in cwg2504.cpp
1414

15+
namespace cwg2512 { // cwg2512: 2.7
16+
struct A; // #cwg2512-A
17+
void foo(A* p) {
18+
typeid(*p);
19+
// expected-error@-1 {{'typeid' of incomplete type 'A'}}
20+
// expected-note@#cwg2512-A {{forward declaration of 'cwg2512::A'}}
21+
}
22+
} // namespace cwg2512
23+
1524
namespace cwg2516 { // cwg2516: 3.0
1625
// NB: reusing 1482 test
1726
#if __cplusplus >= 201103L

clang/test/CXX/drs/cwg2630.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: split-file --leading-lines %s %t
2+
// RUN: %clang_cc1 -std=c++20 -verify -emit-module-interface %t/module.cppm -o %t/module.pcm
3+
// RUN: %clang_cc1 -std=c++20 -verify -fmodule-file=A=%t/module.pcm %t/main.cpp
4+
// RUN: %clang_cc1 -std=c++23 -verify -emit-module-interface %t/module.cppm -o %t/module.pcm
5+
// RUN: %clang_cc1 -std=c++23 -verify -fmodule-file=A=%t/module.pcm %t/main.cpp
6+
// RUN: %clang_cc1 -std=c++2c -verify -emit-module-interface %t/module.cppm -o %t/module.pcm
7+
// RUN: %clang_cc1 -std=c++2c -verify -fmodule-file=A=%t/module.pcm %t/main.cpp
8+
9+
//--- module.cppm
10+
// expected-no-diagnostics
11+
export module A;
12+
13+
namespace cwg2630 {
14+
export class X {};
15+
} // namespace cwg2630
16+
17+
//--- main.cpp
18+
// expected-no-diagnostics
19+
import A;
20+
21+
namespace cwg2630 { // cwg2630: 9
22+
X x;
23+
} // namespace cwg2630

clang/test/CXX/drs/cwg26xx.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ void f() {
4949
#endif
5050
}
5151

52+
// cwg2630 is in cwg2630.cpp
53+
5254
namespace cwg2631 { // cwg2631: 16
5355
#if __cplusplus >= 202002L
5456
constexpr int g();

clang/test/CXX/drs/cwg27xx.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,17 @@
66
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -verify=expected,since-cxx23 %s
77
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++2c -verify=expected,since-cxx23,since-cxx26 %s
88

9-
#if __cplusplus <= 202002L
10-
// expected-no-diagnostics
11-
#endif
9+
namespace cwg2718 { // cwg2718: 2.7
10+
struct B {};
11+
struct D;
12+
13+
void f(B b) {
14+
static_cast<D&>(b);
15+
// expected-error@-1 {{non-const lvalue reference to type 'D' cannot bind to a value of unrelated type 'B'}}
16+
}
17+
18+
struct D : B {};
19+
} // namespace cwg2718
1220

1321
namespace cwg2759 { // cwg2759: 19
1422
#if __cplusplus >= 201103L

clang/test/CXX/drs/cwg28xx.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
// RUN: %clang_cc1 -std=c++23 -verify=expected,since-cxx20,since-cxx23 %s
77
// RUN: %clang_cc1 -std=c++2c -verify=expected,since-cxx20,since-cxx23,since-cxx26 %s
88

9-
#if __cplusplus < 202002L
10-
// expected-no-diagnostics
11-
#endif
12-
139
namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01
1410
#if __cpp_constexpr >= 202306L
1511
constexpr void* p = nullptr;
@@ -67,6 +63,30 @@ void B<int>::g() requires true;
6763

6864
} // namespace cwg2847
6965

66+
namespace cwg2857 { // cwg2857: no
67+
struct A {};
68+
template <typename>
69+
struct D;
70+
namespace N {
71+
struct B {};
72+
void adl_only(A*, D<int>*); // #cwg2857-adl_only
73+
}
74+
75+
void f(A* a, D<int>* d) {
76+
adl_only(a, d);
77+
// expected-error@-1 {{use of undeclared identifier 'adl_only'; did you mean 'N::adl_only'?}}
78+
// expected-note@#cwg2857-adl_only {{'N::adl_only' declared here}}
79+
}
80+
81+
#if __cplusplus >= 201103L
82+
template <typename>
83+
struct D : N::B {
84+
// FIXME: ADL shouldn't associate it's base B and N since D is not complete here
85+
decltype(adl_only((A*) nullptr, (D*) nullptr)) f;
86+
};
87+
#endif
88+
} // namespace cwg2857
89+
7090
namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
7191

7292
#if __cplusplus > 202302L

clang/test/CXX/drs/cwg9xx.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ namespace std {
1414
};
1515
}
1616

17+
namespace cwg930 { // cwg930: 2.7
18+
#if __cplusplus >= 201103L
19+
static_assert(alignof(int[]) == alignof(int), "");
20+
static_assert(alignof(int[][2]) == alignof(int[2]), "");
21+
#endif
22+
} // namespace cwg930
23+
1724
namespace cwg948 { // cwg948: 3.7
1825
#if __cplusplus >= 201103L
1926
class A {

0 commit comments

Comments
 (0)