Author: Richard Smith Date: 2025-10-30T15:50:45-07:00 New Revision: 1e3a1ce911d1e5e3804b63e3ba3059c36eb697e5
URL: https://github.com/llvm/llvm-project/commit/1e3a1ce911d1e5e3804b63e3ba3059c36eb697e5 DIFF: https://github.com/llvm/llvm-project/commit/1e3a1ce911d1e5e3804b63e3ba3059c36eb697e5.diff LOG: 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 <[email protected]> Added: clang/test/CXX/drs/cwg6.cpp Modified: clang/test/CXX/drs/cwg0xx.cpp clang/test/CXX/drs/cwg28xx.cpp clang/test/CXX/drs/cwg2xx.cpp clang/www/cxx_dr_status.html Removed: ################################################################################ diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp index 805be67f2dc1a..10a4f1d6add3a 100644 --- a/clang/test/CXX/drs/cwg0xx.cpp +++ b/clang/test/CXX/drs/cwg0xx.cpp @@ -90,6 +90,8 @@ namespace cwg5 { // cwg5: 3.1 const C c = e; } // namespace cwg5 +// cwg6 is in cwg6.cpp + namespace cwg7 { // cwg7: 3.4 class A { public: ~A(); }; class B : virtual private A {}; // #cwg7-B diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp index a6b2b99e0c3f1..d0ee191ef23d8 100644 --- a/clang/test/CXX/drs/cwg28xx.cpp +++ b/clang/test/CXX/drs/cwg28xx.cpp @@ -61,6 +61,24 @@ namespace cwg2819 { // cwg2819: 19 c++26 #endif } // namespace cwg2819 +namespace cwg2823 { // cwg2823: no +#if __cplusplus >= 201103L + constexpr int *p = 0; + constexpr int *q1 = &*p; + // expected-error@-1 {{constexpr variable 'q1' must be initialized by a constant expression}} + // expected-note@-2 {{dereferencing a null pointer is not allowed in a constant expression}} + // FIXME: invalid: dereferencing a null pointer. + constexpr int *q2 = &p[0]; + + int arr[32]; + constexpr int *r = arr; + // FIXME: invalid: dereferencing a past-the-end pointer. + constexpr int *s1 = &*(r + 32); + // FIXME: invalid: dereferencing a past-the-end pointer. + constexpr int *s2 = &r[32]; +#endif +} + namespace cwg2847 { // cwg2847: 19 review 2024-03-01 #if __cplusplus >= 202002L diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp index 37186e3c3f205..a4995ddc2c588 100644 --- a/clang/test/CXX/drs/cwg2xx.cpp +++ b/clang/test/CXX/drs/cwg2xx.cpp @@ -230,6 +230,38 @@ namespace cwg211 { // cwg211: 2.7 }; } // namespace cwg211 +namespace cwg212 { // cwg212: 2.7 + template<typename T> struct Base; + template<typename T> struct Derived; + + int *overload(void*); + float *overload(Base<int>*); + double *overload(Base<long>*); + + void f(Derived<int> *p) { + // OK, calls void* overload. + int *a = overload(p); + + Base<int> *q = p; + // expected-error@-1 {{cannot initialize a variable of type 'Base<int> *' with an lvalue of type 'Derived<int> *'}} + } + + template<typename T> struct Base {}; + template<typename T> struct Derived : Base<T> {}; + + void g(Derived<long> *p) { + // OK, instantiates and calls Base<long>* overlod. + double *b = overload(p); + (void)b; + } + + void h(Derived<float> *p) { + // OK, instantiates and converts. + Base<float> *q = p; + (void)q; + } +} + namespace cwg213 { // cwg213: 2.7 template <class T> struct A : T { void h(T t) { @@ -593,6 +625,9 @@ namespace cwg231 { // cwg231: 2.7 } } // namespace cwg231 +// 232 is NAD; the desired behavior is described in 2823. +// cwg232: dup 2823 + // cwg234: na // cwg235: na diff --git a/clang/test/CXX/drs/cwg6.cpp b/clang/test/CXX/drs/cwg6.cpp new file mode 100644 index 0000000000000..4752e72034c78 --- /dev/null +++ b/clang/test/CXX/drs/cwg6.cpp @@ -0,0 +1,51 @@ +// 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 +// 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 +// 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 +// 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 +// 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 +// 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 +// 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 + +#if __cplusplus == 199711L +#define static_assert(expr) __extension__ _Static_assert(expr) +#define noexcept throw() +#endif + +namespace cwg6 { // cwg6: 2.7 +#if __cplusplus >= 201103L +struct Counter { + int copies; + constexpr Counter(int copies) : copies(copies) {} + constexpr Counter(const Counter& other) : copies(other.copies + 1) {} +}; + +// Passing an lvalue by value makes a non-elidable copy. +constexpr int PassByValue(Counter c) { return c.copies; } +constexpr int PassByValue2(Counter c) { return PassByValue(c); } +constexpr int PassByValue3(Counter c) { return PassByValue2(c); } +static_assert(PassByValue(Counter(0)) == 0, "expect no copies"); +static_assert(PassByValue2(Counter(0)) == 1, "expect 1 copy"); +static_assert(PassByValue3(Counter(0)) == 2, "expect 2 copies"); +#endif + +struct A { + A() noexcept; + A(const A&) noexcept; + ~A() noexcept; +}; + +inline void f(A a) noexcept {} + +// CHECK-LABEL: define {{.*}} @_ZN4cwg64callEv +void call() { + A a; + // We copy the parameter here, even though object is not mutated by f and + // otherwise satisfies the criteria for the proposed CWG6 optimization. + // CHECK: call {{.*}} @_ZN4cwg61AC1ERKS0_( + // CHECK: call {{.*}} @_ZN4cwg61fENS_1AE( + f(a); + // CHECK: call {{.*}} @_ZN4cwg61AD1Ev( + // CHECK: call {{.*}} @_ZN4cwg61AD1Ev( +} + +} // namespace cwg6 diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index ae9b28ee625cd..0312c9dfc0665 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -81,7 +81,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td><a href="https://cplusplus.github.io/CWG/issues/6.html">6</a></td> <td>NAD</td> <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> - <td class="unknown" align="center">Unknown</td> + <td class="full" align="center">Yes</td> </tr> <tr id="7"> <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> <td><a href="https://cplusplus.github.io/CWG/issues/212.html">212</a></td> <td>CD4</td> <td>Implicit instantiation is not described clearly enough</td> - <td class="unknown" align="center">Unknown</td> + <td class="full" align="center">Yes</td> </tr> <tr id="213"> <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> <td><a href="https://cplusplus.github.io/CWG/issues/232.html">232</a></td> <td>NAD</td> <td>Is indirection through a null pointer undefined behavior?</td> - <td class="unknown" align="center">Unknown</td> + <td class="none" align="center">Duplicate of <a href="#2823">2823</a></td> </tr> <tr id="233"> <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> <td><a href="https://cplusplus.github.io/CWG/issues/2823.html">2823</a></td> <td>CD7</td> <td>Implicit undefined behavior when dereferencing pointers</td> - <td class="unknown" align="center">Unknown</td> + <td class="none" align="center">No</td> </tr> <tr id="2824"> <td><a href="https://cplusplus.github.io/CWG/issues/2824.html">2824</a></td> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
