-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] Add tests for CWG issues regarding completeness of types #92113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Vlad Serebrennikov (Endilll) ChangesThis patch covers the following Core issues: Current wording for CWG1110 came from 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 Full diff: https://github.com/llvm/llvm-project/pull/92113.diff 12 Files Affected:
diff --git a/clang/test/CXX/drs/cwg11xx.cpp b/clang/test/CXX/drs/cwg11xx.cpp
index 46a0e526be390..8d187041400a6 100644
--- a/clang/test/CXX/drs/cwg11xx.cpp
+++ b/clang/test/CXX/drs/cwg11xx.cpp
@@ -4,6 +4,21 @@
// RUN: %clang_cc1 -std=c++17 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++2a %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+namespace cwg1110 { // cwg1110: 3.1
+#if __cplusplus >= 201103L
+template <typename T>
+T return_T();
+
+struct A;
+
+template <typename>
+struct B;
+
+decltype(return_T<A>())* a;
+decltype(return_T<B<int>>())* b;
+#endif
+} // namespace cwg1110
+
namespace cwg1111 { // cwg1111: 3.2
namespace example1 {
template <typename> struct set; // #cwg1111-struct-set
diff --git a/clang/test/CXX/drs/cwg13xx.cpp b/clang/test/CXX/drs/cwg13xx.cpp
index a334b6d01acf5..416de7c536b1a 100644
--- a/clang/test/CXX/drs/cwg13xx.cpp
+++ b/clang/test/CXX/drs/cwg13xx.cpp
@@ -306,6 +306,18 @@ namespace cwg1330 { // cwg1330: 4 c++11
// cwg1334: sup 1719
+namespace cwg1340 { // cwg1340: 2.9
+struct A;
+struct B;
+
+void f(B* a, A B::* p) {
+ (*a).*p;
+ // expected-warning@-1 {{expression result unused}}
+ a->*p;
+ // expected-warning@-1 {{expression result unused}}
+}
+} // namespace cwg1340
+
namespace cwg1341 { // cwg1341: sup P0683R1
#if __cplusplus >= 202002L
int a;
@@ -451,6 +463,25 @@ static_assert(!__is_nothrow_constructible(D4, int), "");
#endif
} // namespace cwg1350
+namespace cwg1352 { // cwg1352: 3.0
+struct A {
+#if __cplusplus >= 201103L
+ int a = sizeof(A);
+#endif
+ void f(int b = sizeof(A));
+};
+
+template <typename T>
+struct B {
+#if __cplusplus >= 201103L
+ int a = sizeof(B) + sizeof(T);
+#endif
+ void f(int b = sizeof(B) + sizeof(T));
+};
+
+template class B<int>;
+} // namespace cwg1352
+
namespace cwg1358 { // cwg1358: 3.1
#if __cplusplus >= 201103L
struct Lit { constexpr operator int() const { return 0; } };
diff --git a/clang/test/CXX/drs/cwg14xx.cpp b/clang/test/CXX/drs/cwg14xx.cpp
index 9ff9a68dc13c3..f01d96ad47f3e 100644
--- a/clang/test/CXX/drs/cwg14xx.cpp
+++ b/clang/test/CXX/drs/cwg14xx.cpp
@@ -86,6 +86,23 @@ struct A {
};
}
+namespace cwg1458 { // cwg1458: 3.1
+#if __cplusplus >= 201103L
+struct A;
+
+void f() {
+ constexpr A* a = nullptr;
+ constexpr int p = &*a;
+ // expected-error@-1 {{cannot initialize a variable of type 'const int' with an rvalue of type 'A *'}}
+ constexpr A *p2 = &*a;
+}
+
+struct A {
+ int operator&();
+};
+#endif
+} // namespace cwg1458
+
namespace cwg1460 { // cwg1460: 3.5
#if __cplusplus >= 201103L
namespace DRExample {
diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp
index 9eb749153e57a..89adc28384904 100644
--- a/clang/test/CXX/drs/cwg18xx.cpp
+++ b/clang/test/CXX/drs/cwg18xx.cpp
@@ -206,7 +206,7 @@ namespace cwg1814 { // cwg1814: yes
#endif
}
-namespace cwg1815 { // cwg1815: yes
+namespace cwg1815 { // cwg1815: 19
#if __cplusplus >= 201402L
struct A { int &&r = 0; };
A a = {};
@@ -303,6 +303,32 @@ namespace cwg1822 { // cwg1822: yes
#endif
}
+namespace cwg1824 { // cwg1824: 2.7
+template<typename T>
+struct A {
+ T t;
+};
+
+struct S {
+ A<S> f() { return A<S>(); }
+};
+} // namespace cwg1824
+
+namespace cwg1832 { // cwg1832: 3.0
+enum E { // #cwg1832-E
+ a = static_cast<int>(static_cast<E>(0))
+ // expected-error@-1 {{'E' is an incomplete type}}
+ // expected-note@#cwg1832-E {{definition of 'cwg1832::E' is not complete until the closing '}'}}
+};
+
+#if __cplusplus >= 201103L
+enum E2: decltype(static_cast<E2>(0), 0) {};
+// expected-error@-1 {{unknown type name 'E2'}}
+enum class E3: decltype(static_cast<E3>(0), 0) {};
+// expected-error@-1 {{unknown type name 'E3'}}
+#endif
+} // namespace cwg1832
+
namespace cwg1837 { // cwg1837: 3.3
#if __cplusplus >= 201103L
template <typename T>
diff --git a/clang/test/CXX/drs/cwg23xx.cpp b/clang/test/CXX/drs/cwg23xx.cpp
index db5b7c3cd3c9a..c671a770f3b28 100644
--- a/clang/test/CXX/drs/cwg23xx.cpp
+++ b/clang/test/CXX/drs/cwg23xx.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx11-14,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
// 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
// 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,47 @@ void g() {
} // namespace cwg2303
#endif
+namespace cwg2304 { // cwg2304: 2.8
+template<typename T> void foo(T, int);
+template<typename T> void foo(T&, ...);
+struct Q; // #cwg2304-Q
+void fn1(Q &data_vectors) {
+ foo(data_vectors, 0);
+ // expected-error@-1 {{argument type 'cwg2304::Q' is incomplete}}
+ // expected-note@#cwg2304-Q {{forward declaration of 'cwg2304::Q'}}
+}
+} // namespace cwg2304
+
+namespace cwg2310 { // cwg2310: partial
+#if __cplusplus >= 201103L
+template<typename A, typename B>
+struct check_derived_from {
+ static A a;
+ // FIXME: all 3 examples should be rejected in all language modes.
+ // FIXME: we should test this in 98 mode.
+ static constexpr B *p = &a;
+ // cxx11-14-error@-1 {{cannot initialize a variable of type 'cwg2310::X *const' with an rvalue of type 'cwg2310::Z *'}}
+ // cxx11-14-note@#cwg2310-X {{in instantiation of template class 'cwg2310::check_derived_from<cwg2310::Z, cwg2310::X>' requested here}}
+ // cxx11-14-error@-3 {{cannot initialize a variable of type 'cwg2310::Y *const' with an rvalue of type 'cwg2310::Z *'}}
+ // cxx11-14-note@#cwg2310-Y {{in instantiation of template class 'cwg2310::check_derived_from<cwg2310::Z, cwg2310::Y>' requested here}}
+};
+
+struct W {};
+struct X {};
+struct Y {};
+struct Z : W,
+ X, check_derived_from<Z, X>, // #cwg2310-X
+ check_derived_from<Z, Y>, Y // #cwg2310-Y
+{
+ // FIXME: It was properly rejected before, but we're crashing since Clang 11 in C++11 and C++14 modes.
+ // See https://github.com/llvm/llvm-project/issues/59920
+#if __cplusplus >= 201703L
+ check_derived_from<Z, W> cdf;
+#endif
+};
+#endif
+} // namespace cwg2310
+
// cwg2331: na
// cwg2335 is in cwg2335.cxx
diff --git a/clang/test/CXX/drs/cwg24xx.cpp b/clang/test/CXX/drs/cwg24xx.cpp
index 9f876cd870834..75e1a614765c5 100644
--- a/clang/test/CXX/drs/cwg24xx.cpp
+++ b/clang/test/CXX/drs/cwg24xx.cpp
@@ -45,6 +45,12 @@ void fallthrough(int n) {
#endif
}
+namespace cwg2430 { // cwg2430: 2.7
+struct S {
+ S f(S s) { return s; }
+};
+} // namespace cwg2430
+
namespace cwg2450 { // cwg2450: 18
#if __cplusplus >= 202302L
struct S {int a;};
diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp
index 8bca58f44944f..0934f0cc19c6a 100644
--- a/clang/test/CXX/drs/cwg25xx.cpp
+++ b/clang/test/CXX/drs/cwg25xx.cpp
@@ -6,12 +6,21 @@
// 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
// 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
-#if __cplusplus == 199711L
-// expected-no-diagnostics
-#endif
+namespace std {
+struct type_info{};
+} // namespace std
// cwg2504 is in cwg2504.cpp
+namespace cwg2512 { // cwg2512: 2.7
+struct A; // #cwg2512-A
+void foo(A* p) {
+ typeid(*p);
+ // expected-error@-1 {{'typeid' of incomplete type 'A'}}
+ // expected-note@#cwg2512-A {{forward declaration of 'cwg2512::A'}}
+}
+} // namespace cwg2512
+
namespace cwg2516 { // cwg2516: 3.0
// NB: reusing 1482 test
#if __cplusplus >= 201103L
diff --git a/clang/test/CXX/drs/cwg26xx.cpp b/clang/test/CXX/drs/cwg26xx.cpp
index f7a05b9827a23..f88b021a83c87 100644
--- a/clang/test/CXX/drs/cwg26xx.cpp
+++ b/clang/test/CXX/drs/cwg26xx.cpp
@@ -49,6 +49,8 @@ void f() {
#endif
}
+// cwg2630: na
+
namespace cwg2631 { // cwg2631: 16
#if __cplusplus >= 202002L
constexpr int g();
diff --git a/clang/test/CXX/drs/cwg27xx.cpp b/clang/test/CXX/drs/cwg27xx.cpp
index 0434427d6c92a..53ddd566b7dbf 100644
--- a/clang/test/CXX/drs/cwg27xx.cpp
+++ b/clang/test/CXX/drs/cwg27xx.cpp
@@ -6,9 +6,17 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -verify=expected,since-cxx23 %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++2c -verify=expected,since-cxx23,since-cxx26 %s
-#if __cplusplus <= 202002L
-// expected-no-diagnostics
-#endif
+namespace cwg2718 { // cwg2718: 2.7
+struct B {};
+struct D;
+
+void f(B b) {
+ static_cast<D&>(b);
+ // expected-error@-1 {{non-const lvalue reference to type 'D' cannot bind to a value of unrelated type 'B'}}
+}
+
+struct D : B {};
+} // namespace cwg2718
namespace cwg2759 { // cwg2759: 19
#if __cplusplus >= 201103L
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index be35d366bdd61..818297183fc62 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -6,10 +6,6 @@
// RUN: %clang_cc1 -std=c++23 -verify=expected,since-cxx20,since-cxx23 %s
// RUN: %clang_cc1 -std=c++2c -verify=expected,since-cxx20,since-cxx23,since-cxx26 %s
-#if __cplusplus < 202002L
-// expected-no-diagnostics
-#endif
-
namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01
#if __cpp_constexpr >= 202306L
constexpr void* p = nullptr;
@@ -67,6 +63,27 @@ void B<int>::g() requires true;
} // namespace cwg2847
+namespace cwg2857 { // cwg2857: 2.7
+struct A {};
+struct B {
+ int operator+(A);
+};
+template <typename>
+struct D;
+
+void f(A* a, D<int>* d) {
+ *d + *a;
+ // expected-error@-1 {{invalid operands to binary expression ('D<int>' and 'A')}}
+}
+
+template <typename>
+struct D : B {};
+
+void g(A* a, D<int>* d) {
+ *d + *a;
+}
+} // namespace cwg2857
+
namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
#if __cplusplus > 202302L
diff --git a/clang/test/CXX/drs/cwg9xx.cpp b/clang/test/CXX/drs/cwg9xx.cpp
index 8ecb149c355f6..2700b0f5662a2 100644
--- a/clang/test/CXX/drs/cwg9xx.cpp
+++ b/clang/test/CXX/drs/cwg9xx.cpp
@@ -14,6 +14,13 @@ namespace std {
};
}
+namespace cwg930 { // cwg930: 2.7
+#if __cplusplus >= 201103L
+static_assert(alignof(int[]) == alignof(int), "");
+static_assert(alignof(int[][2]) == alignof(int[2]), "");
+#endif
+} // namespace cwg930
+
namespace cwg948 { // cwg948: 3.7
#if __cplusplus >= 201103L
class A {
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 92fdcf5556ede..d531dbc1469f1 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -5388,7 +5388,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/930.html">930</a></td>
<td>CD2</td>
<td><TT>alignof</TT> with incomplete array type</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.7</td>
</tr>
<tr id="931">
<td><a href="https://cplusplus.github.io/CWG/issues/931.html">931</a></td>
@@ -6468,7 +6468,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1110.html">1110</a></td>
<td>NAD</td>
<td>Incomplete return type should be allowed in <TT>decltype</TT> operand</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 3.1</td>
</tr>
<tr id="1111">
<td><a href="https://cplusplus.github.io/CWG/issues/1111.html">1111</a></td>
@@ -7848,7 +7848,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1340.html">1340</a></td>
<td>CD3</td>
<td>Complete type in member pointer expressions</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.9</td>
</tr>
<tr id="1341">
<td><a href="https://cplusplus.github.io/CWG/issues/1341.html">1341</a></td>
@@ -7920,7 +7920,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1352.html">1352</a></td>
<td>CD3</td>
<td>Inconsistent class scope and completeness rules</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 3.0</td>
</tr>
<tr id="1353">
<td><a href="https://cplusplus.github.io/CWG/issues/1353.html">1353</a></td>
@@ -8556,7 +8556,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1458.html">1458</a></td>
<td>CD3</td>
<td>Address of incomplete type vs <TT>operator&()</TT></td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 3.1</td>
</tr>
<tr class="open" id="1459">
<td><a href="https://cplusplus.github.io/CWG/issues/1459.html">1459</a></td>
@@ -10752,7 +10752,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1824.html">1824</a></td>
<td>CD4</td>
<td>Completeness of return type vs point of instantiation</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.7</td>
</tr>
<tr id="1825">
<td><a href="https://cplusplus.github.io/CWG/issues/1825.html">1825</a></td>
@@ -10800,7 +10800,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1832.html">1832</a></td>
<td>CD4</td>
<td>Casting to incomplete enumeration</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 3.0</td>
</tr>
<tr id="1833">
<td><a href="https://cplusplus.github.io/CWG/issues/1833.html">1833</a></td>
@@ -13632,7 +13632,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2304.html">2304</a></td>
<td>NAD</td>
<td>Incomplete type vs overload resolution</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.8</td>
</tr>
<tr id="2305">
<td><a href="https://cplusplus.github.io/CWG/issues/2305.html">2305</a></td>
@@ -13668,7 +13668,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2310.html">2310</a></td>
<td>CD5</td>
<td>Type completeness and derived-to-base pointer conversions</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="partial" align="center">Partial</td>
</tr>
<tr class="open" id="2311">
<td><a href="https://cplusplus.github.io/CWG/issues/2311.html">2311</a></td>
@@ -14388,7 +14388,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2430.html">2430</a></td>
<td>C++20</td>
<td>Completeness of return and parameter types of member functions</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.7</td>
</tr>
<tr id="2431">
<td><a href="https://cplusplus.github.io/CWG/issues/2431.html">2431</a></td>
@@ -14880,7 +14880,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2512.html">2512</a></td>
<td>NAD</td>
<td><TT>typeid</TT> and incomplete class types</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.7</td>
</tr>
<tr class="open" id="2513">
<td><a href="https://cplusplus.github.io/CWG/issues/2513.html">2513</a></td>
@@ -15588,7 +15588,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2630.html">2630</a></td>
<td>C++23</td>
<td>Syntactic specification of class completeness</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="na" align="center">N/A</td>
</tr>
<tr id="2631">
<td><a href="https://cplusplus.github.io/CWG/issues/2631.html">2631</a></td>
@@ -16116,7 +16116,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2718.html">2718</a></td>
<td>DRWP</td>
<td>Type completeness for derived-to-base conversions</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.7</td>
</tr>
<tr id="2719">
<td><a href="https://cplusplus.github.io/CWG/issues/2719.html">2719</a></td>
@@ -16951,7 +16951,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2857.html">2857</a></td>
<td>DR</td>
<td>Argument-dependent lookup with incomplete class types</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Clang 2.7</td>
</tr>
<tr class="open" id="2858">
<td><a href="https://cplusplus.github.io/CWG/issues/2858.html">2858</a></td>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! LGTM! 🤩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great.
My only question is about cwg2630
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM w/ a few nitpicks
namespace cwg1352 { // cwg1352: 3.0 | ||
struct A { | ||
#if __cplusplus >= 201103L | ||
int a = sizeof(A); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be worth it to see that this fails for a static member
since the DR specifically says non-static
so we should cover both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also mentions in the body of member function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not going to fail for static member initializers because of (I suspect) subsequent changes that were made to the wording: http://eel.is/c++draft/class.mem.general#8.5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also mentions in the body of member function
Yeah, that is worth adding. I'll prepare a PR.
constexpr A* a = nullptr; | ||
constexpr int p = &*a; | ||
// expected-error@-1 {{cannot initialize a variable of type 'const int' with an rvalue of type 'A *'}} | ||
constexpr A *p2 = &*a; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the DR says it is "unspecified" so are we documenting here that this will always be the behavior? Maybe worth a comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are documenting that our constant evaluator doesn't consider this UB.
This patch covers the following Core issues:
CWG930 "
alignof
with incomplete array type"CWG1110 "Incomplete return type should be allowed in
decltype
operand"CWG1340 "Complete type in member pointer expressions"
CWG1352 "Inconsistent class scope and completeness rules"
CWG1458 "Address of incomplete type vs
operator&()
"CWG1824 "Completeness of return type vs point of instantiation"
CWG1832 "Casting to incomplete enumeration"
CWG2304 "Incomplete type vs overload resolution"
CWG2310 "Type completeness and derived-to-base pointer conversions"
CWG2430 "Completeness of return and parameter types of member functions"
CWG2512 "
typeid
and incomplete class types"CWG2630 "Syntactic specification of class completeness"
CWG2718 "Type completeness for derived-to-base conversions"
CWG2857 "Argument-dependent lookup with incomplete class types"
Current wording for CWG1110 came from 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