https://github.com/MitalAshok updated https://github.com/llvm/llvm-project/pull/78060
>From 6ed7cad5d4993603221c3d9a777463675d69643b Mon Sep 17 00:00:00 2001 From: Mital Ashok <mi...@mitalashok.co.uk> Date: Sat, 13 Jan 2024 18:03:15 +0000 Subject: [PATCH 1/4] [SemaCXX] Implement CWG2351 `void{}` --- clang/docs/ReleaseNotes.rst | 3 ++ clang/include/clang/AST/ExprCXX.h | 5 +-- clang/lib/Sema/SemaExprCXX.cpp | 23 ++++++++---- clang/lib/Sema/SemaInit.cpp | 1 + clang/test/CXX/drs/dr23xx.cpp | 41 +++++++++++++++++++++- clang/test/SemaCXX/attr-annotate.cpp | 4 +-- clang/test/SemaCXX/cxx2a-explicit-bool.cpp | 4 +-- clang/test/SemaCXX/sugared-auto.cpp | 6 ++++ clang/www/cxx_dr_status.html | 2 +- 9 files changed, 75 insertions(+), 14 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 92563262cc6737..28cd1a8abd4c65 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -157,6 +157,9 @@ Resolutions to C++ Defect Reports - Clang now diagnoses declarative nested-name-specifiers with pack-index-specifiers. (`CWG2858: Declarative nested-name-specifiers and pack-index-specifiers <https://cplusplus.github.io/CWG/issues/2858.html>`_). +- Implemented `CWG2351 <https://wg21.link/CWG2351>`_ which allows ``void{}`` + as a prvalue of type ``void``. + C Language Changes ------------------ diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index a915745d2d7322..8fa5c0c79f6a02 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -2170,8 +2170,9 @@ class LambdaExpr final : public Expr, const_child_range children() const; }; -/// An expression "T()" which creates a value-initialized rvalue of type -/// T, which is a non-class type. See (C++98 [5.2.3p2]). +/// An expression "T()" which creates an rvalue of a non-class type T. +/// For non-void T, the rvalue is value-initialized. +/// See (C++98 [5.2.3p2]). class CXXScalarValueInitExpr : public Expr { friend class ASTStmtReader; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 779a41620033dc..269aedb59ca8f1 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1660,12 +1660,23 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, return ExprError(Diag(TyBeginLoc, diag::err_init_for_function_type) << Ty << FullRange); - // C++17 [expr.type.conv]p2: - // If the type is cv void and the initializer is (), the expression is a - // prvalue of the specified type that performs no initialization. - if (!Ty->isVoidType() && - RequireCompleteType(TyBeginLoc, ElemTy, - diag::err_invalid_incomplete_type_use, FullRange)) + // C++17 [expr.type.conv]p2, per DR2351: + // If the type is cv void and the initializer is () or {}, the expression is + // a prvalue of the specified type that performs no initialization. + if (Ty->isVoidType()) { + if (Exprs.empty()) + return new (Context) CXXScalarValueInitExpr( + Ty.getUnqualifiedType(), TInfo, Kind.getRange().getEnd()); + if (ListInitialization && + cast<InitListExpr>(Exprs[0])->getNumInits() == 0) { + return CXXFunctionalCastExpr::Create( + Context, Ty.getUnqualifiedType(), VK_PRValue, TInfo, CK_NoOp, + Exprs[0], /*Path=*/nullptr, CurFPFeatureOverrides(), + Exprs[0]->getBeginLoc(), Exprs[0]->getEndLoc()); + } + } else if (RequireCompleteType(TyBeginLoc, ElemTy, + diag::err_invalid_incomplete_type_use, + FullRange)) return ExprError(); // Otherwise, the expression is a prvalue of the specified type whose diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 003a157990d307..3bb8407c893d9d 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -5344,6 +5344,7 @@ static void TryValueInitialization(Sema &S, // // To value-initialize an object of type T means: QualType T = Entity.getType(); + assert(!T->isVoidType() && "Cannot value-init void"); // -- if T is an array type, then each element is value-initialized; T = S.Context.getBaseElementType(T); diff --git a/clang/test/CXX/drs/dr23xx.cpp b/clang/test/CXX/drs/dr23xx.cpp index db5b7c3cd3c9a2..cd21af0daf3d0f 100644 --- a/clang/test/CXX/drs/dr23xx.cpp +++ b/clang/test/CXX/drs/dr23xx.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s +// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-03 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s +// RUN: %clang_cc1 -std=c++03 %s -verify=expected,cxx98-03 -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++17 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s @@ -70,6 +71,44 @@ namespace cwg2346 { // cwg2346: 11 } } +namespace cwg2351 { // cwg2351: 19 +#if __cplusplus >= 201103L + static_assert((void{}, true), ""); + // since-cxx11-warning@-1 {{left operand of comma operator has no effect}} + + void f() { + return void{}; + } + + template<typename T> + void g() { + return T{}; + } + template void g<void>(); + template void g<const void>(); + + void h() { + return {}; + // since-cxx11-error@-1 {{void function 'h' must not return a value}} + } + + template<typename T, int... I> + T i() { + return T{I...}; + } + template void i<void>(); + template const void i<const void>(); + + static_assert((void({}), true), ""); + // since-cxx11-error@-1 {{cannot initialize non-class type 'void' with a parenthesized initializer list}} +#else + int I = (void{}, 0); + // cxx98-03-error@-1 {{expected ')'}} + // cxx98-03-note@-2 {{to match this '('}} + // cxx98-03-error@-3 {{expected expression}} +#endif +} + namespace cwg2352 { // cwg2352: 10 int **p; const int *const *const &f1() { return p; } diff --git a/clang/test/SemaCXX/attr-annotate.cpp b/clang/test/SemaCXX/attr-annotate.cpp index 3854f72bbcac1c..846ef4119f1d7c 100644 --- a/clang/test/SemaCXX/attr-annotate.cpp +++ b/clang/test/SemaCXX/attr-annotate.cpp @@ -43,10 +43,10 @@ namespace test0 { template<typename T> struct B { [[clang::annotate("test", ((void)T{}, 9))]] void t() {} - // expected-error@-1 {{illegal initializer type 'void'}} + // expected-error@-1 {{cannot create object of function type 'void ()'}} }; B<int> b; - B<void> b1; + B<void ()> b1; // expected-note@-1 {{in instantiation of template class}} } diff --git a/clang/test/SemaCXX/cxx2a-explicit-bool.cpp b/clang/test/SemaCXX/cxx2a-explicit-bool.cpp index 9fdc059493aacb..55f99b2fd355ff 100644 --- a/clang/test/SemaCXX/cxx2a-explicit-bool.cpp +++ b/clang/test/SemaCXX/cxx2a-explicit-bool.cpp @@ -75,11 +75,11 @@ struct D { template <typename T> struct E { // expected-note@-1+ {{candidate constructor}} explicit((T{}, false)) - // expected-error@-1 {{illegal initializer type 'void'}} + // expected-error@-1 {{cannot create object of function type 'void ()'}} E(int); }; -E<void> e = 1; +E<void ()> e = 1; // expected-error@-1 {{no viable conversion}} // expected-note@-2 {{in instantiation of}} diff --git a/clang/test/SemaCXX/sugared-auto.cpp b/clang/test/SemaCXX/sugared-auto.cpp index 5fdfb09689b667..b5bb4f0f85a775 100644 --- a/clang/test/SemaCXX/sugared-auto.cpp +++ b/clang/test/SemaCXX/sugared-auto.cpp @@ -112,6 +112,12 @@ N t6 = [] { // expected-error {{rvalue of type 'void'}} return; }(); +N t7 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}} + if (true) + return Ebola(); + return SARS{}; +}(); + } // namespace function_multiple_basic #define TEST_AUTO(X, A, B) \ diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index ea8872c91be604..d696cc523e41d2 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -13914,7 +13914,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td><a href="https://cplusplus.github.io/CWG/issues/2351.html">2351</a></td> <td>CD5</td> <td><TT>void{}</TT></td> - <td class="unknown" align="center">Unknown</td> + <td class="unreleased" align="center">Clang 19</td> </tr> <tr id="2352"> <td><a href="https://cplusplus.github.io/CWG/issues/2352.html">2352</a></td> >From 70b62c2246be90ea71dd9b836be55674cc385c0a Mon Sep 17 00:00:00 2001 From: Mital Ashok <mi...@mitalashok.co.uk> Date: Tue, 21 May 2024 16:58:33 +0100 Subject: [PATCH 2/4] Change cast kind to CK_ToVoid instead of CK_NoOp --- clang/docs/ReleaseNotes.rst | 4 ++-- clang/lib/Sema/SemaExprCXX.cpp | 2 +- clang/test/CXX/drs/cwg23xx.cpp | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 0fca837204ba54..67a5cc48043fb2 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -232,8 +232,8 @@ Resolutions to C++ Defect Reports - P0522 implementation is enabled by default in all language versions, and provisional wording for CWG2398 is implemented. -- Implemented `CWG2351 <https://wg21.link/CWG2351>`_ which allows ``void{}`` - as a prvalue of type ``void``. +- Allow ``void{}`` as a prvalue of type ``void``. + (`CWG2351: void{} <https://cplusplus.github.io/CWG/issues/2351.html>`_). C Language Changes ------------------ diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index cfb0091bde51e6..00579eeb1204e4 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1671,7 +1671,7 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, if (ListInitialization && cast<InitListExpr>(Exprs[0])->getNumInits() == 0) { return CXXFunctionalCastExpr::Create( - Context, Ty.getUnqualifiedType(), VK_PRValue, TInfo, CK_NoOp, + Context, Ty.getUnqualifiedType(), VK_PRValue, TInfo, CK_ToVoid, Exprs[0], /*Path=*/nullptr, CurFPFeatureOverrides(), Exprs[0]->getBeginLoc(), Exprs[0]->getEndLoc()); } diff --git a/clang/test/CXX/drs/cwg23xx.cpp b/clang/test/CXX/drs/cwg23xx.cpp index f89865a360b720..3293e92a36f7d9 100644 --- a/clang/test/CXX/drs/cwg23xx.cpp +++ b/clang/test/CXX/drs/cwg23xx.cpp @@ -118,7 +118,6 @@ namespace cwg2346 { // cwg2346: 11 namespace cwg2351 { // cwg2351: 19 #if __cplusplus >= 201103L static_assert((void{}, true), ""); - // since-cxx11-warning@-1 {{left operand of comma operator has no effect}} void f() { return void{}; >From 3540155d2c93ea94de58e9b127f832cf0c28f14e Mon Sep 17 00:00:00 2001 From: Mital Ashok <mi...@mitalashok.co.uk> Date: Sat, 29 Jun 2024 11:41:23 +0100 Subject: [PATCH 3/4] Remove c++03 test that was added It wasn't needed, there is no difference with the C++98 and C++03 behaviour --- clang/test/CXX/drs/cwg23xx.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/clang/test/CXX/drs/cwg23xx.cpp b/clang/test/CXX/drs/cwg23xx.cpp index bbfa14ccd3a4eb..9953b1b6903629 100644 --- a/clang/test/CXX/drs/cwg23xx.cpp +++ b/clang/test/CXX/drs/cwg23xx.cpp @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-03 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s -// RUN: %clang_cc1 -std=c++03 %s -verify=expected,cxx98-03 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s +// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98 -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 @@ -146,9 +145,9 @@ namespace cwg2351 { // cwg2351: 19 // since-cxx11-error@-1 {{cannot initialize non-class type 'void' with a parenthesized initializer list}} #else int I = (void{}, 0); - // cxx98-03-error@-1 {{expected ')'}} - // cxx98-03-note@-2 {{to match this '('}} - // cxx98-03-error@-3 {{expected expression}} + // cxx98-error@-1 {{expected ')'}} + // cxx98-note@-2 {{to match this '('}} + // cxx98-error@-3 {{expected expression}} #endif } >From 5ac0f793b965df5a3b6b7fa674136a444186a5f9 Mon Sep 17 00:00:00 2001 From: Mital Ashok <mi...@mitalashok.co.uk> Date: Thu, 1 Aug 2024 15:39:00 +0100 Subject: [PATCH 4/4] Clang 19 -> Clang 20 --- clang/test/CXX/drs/cwg23xx.cpp | 2 +- clang/www/cxx_dr_status.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/CXX/drs/cwg23xx.cpp b/clang/test/CXX/drs/cwg23xx.cpp index 9953b1b6903629..865445533923b1 100644 --- a/clang/test/CXX/drs/cwg23xx.cpp +++ b/clang/test/CXX/drs/cwg23xx.cpp @@ -114,7 +114,7 @@ namespace cwg2346 { // cwg2346: 11 } } -namespace cwg2351 { // cwg2351: 19 +namespace cwg2351 { // cwg2351: 20 #if __cplusplus >= 201103L static_assert((void{}, true), ""); diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 1f111fba0b7fab..8488a7eca40ab1 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -13914,7 +13914,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td><a href="https://cplusplus.github.io/CWG/issues/2351.html">2351</a></td> <td>CD5</td> <td><TT>void{}</TT></td> - <td class="unreleased" align="center">Clang 19</td> + <td class="unreleased" align="center">Clang 20</td> </tr> <tr id="2352"> <td><a href="https://cplusplus.github.io/CWG/issues/2352.html">2352</a></td> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits