aaron.ballman created this revision. aaron.ballman added reviewers: cor3ntin, erichkeane, royjacobson, clang-language-wg. Herald added a project: All. aaron.ballman requested review of this revision. Herald added a project: clang.
During Clang 15, 3d2629dd3aab17098813c68b5b76bb864bc5e285 <https://reviews.llvm.org/rG3d2629dd3aab17098813c68b5b76bb864bc5e285> claimed we achieved full support for `consteval` in C++20. However, further testing shows that Clang doesn't correctly handle all of the examples from https://wg21.link/P1073R3 and has several other known issues that are preventing us from defining the `__cpp_consteval` macro. I think we should only claim Partial support for the moment. Once we correct the major outstanding issues, then I think we should change the status back to full support and define `__cpp_consteval` at the same time (even if it's only to the `201811L` value instead of the latest value from C++2b). This helps users understand the support situation more clearly. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D144572 Files: clang/test/CXX/expr/expr.const/p6-2a.cpp clang/test/CXX/expr/expr.const/p8-2a.cpp clang/www/cxx_status.html Index: clang/www/cxx_status.html =================================================================== --- clang/www/cxx_status.html +++ clang/www/cxx_status.html @@ -1120,7 +1120,14 @@ <tr> <td rowspan=2>Immediate functions (<tt>consteval</tt>)</td> <td><a href="https://wg21.link/p1073r3">P1073R3</a></td> - <td class="full" align="center">Clang 15</td> + <td class="partial" align="center"> + <details><summary>Clang 15 (Partial)</summary> + Clang still incorrectly defers some consteval executions to runtime, + resulting in CodeGen crashes. Additionally, Clang does not properly + handle default arguments in consteval functions under all + circumstances. + </details> + </td> </tr> <tr> <!-- from Prague --> <td><a href="https://wg21.link/p1937r2">P1937R2</a></td> Index: clang/test/CXX/expr/expr.const/p8-2a.cpp =================================================================== --- /dev/null +++ clang/test/CXX/expr/expr.const/p8-2a.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++20 -verify %s + +// expected-no-diagnostics + +namespace P1073R3 { +struct N { + constexpr N() {} + N(N const&) = delete; +}; + +template<typename T> constexpr void bad_assert_copyable() { T t; T t2 = t; } +using ineffective = decltype(bad_assert_copyable<N>()); + +// bad_assert_copyable<N> is not needed for constant evaluation +// (and thus not instantiated) +template<typename T> consteval void assert_copyable() { T t; T t2 = t; } +using check = decltype(assert_copyable<N>()); +// FIXME: this should give an error because assert_copyable<N> is instantiated +// (because it is needed for constant evaluation), but the attempt to copy t is +// ill-formed. +} // namespace P1073R3 + Index: clang/test/CXX/expr/expr.const/p6-2a.cpp =================================================================== --- clang/test/CXX/expr/expr.const/p6-2a.cpp +++ clang/test/CXX/expr/expr.const/p6-2a.cpp @@ -41,3 +41,16 @@ } }; constexpr Temporary t = {3}; // expected-error {{must have constant destruction}} expected-note {{created here}} expected-note {{in call}} + +namespace P1073R3 { +consteval int f() { return 42; } // expected-note 3 {{declared here}} +consteval auto g() { return f; } +// FIXME: there should be no diagnostics associated with either h() or r. +consteval int h(int (*p)() = g()) { return p(); } // expected-error {{call to consteval function 'P1073R3::g' is not a constant expression}} \ + expected-note {{declared here}} \ + expected-note {{pointer to a consteval declaration is not a constant expression}} +constexpr int r = h(); // expected-note {{in the default initalizer of 'p'}} +constexpr auto e = g(); // expected-error {{call to consteval function 'P1073R3::g' is not a constant expression}} \ + expected-error {{constexpr variable 'e' must be initialized by a constant expression}} \ + expected-note 2 {{pointer to a consteval declaration is not a constant expression}} +} // namespace P1073R3
Index: clang/www/cxx_status.html =================================================================== --- clang/www/cxx_status.html +++ clang/www/cxx_status.html @@ -1120,7 +1120,14 @@ <tr> <td rowspan=2>Immediate functions (<tt>consteval</tt>)</td> <td><a href="https://wg21.link/p1073r3">P1073R3</a></td> - <td class="full" align="center">Clang 15</td> + <td class="partial" align="center"> + <details><summary>Clang 15 (Partial)</summary> + Clang still incorrectly defers some consteval executions to runtime, + resulting in CodeGen crashes. Additionally, Clang does not properly + handle default arguments in consteval functions under all + circumstances. + </details> + </td> </tr> <tr> <!-- from Prague --> <td><a href="https://wg21.link/p1937r2">P1937R2</a></td> Index: clang/test/CXX/expr/expr.const/p8-2a.cpp =================================================================== --- /dev/null +++ clang/test/CXX/expr/expr.const/p8-2a.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++20 -verify %s + +// expected-no-diagnostics + +namespace P1073R3 { +struct N { + constexpr N() {} + N(N const&) = delete; +}; + +template<typename T> constexpr void bad_assert_copyable() { T t; T t2 = t; } +using ineffective = decltype(bad_assert_copyable<N>()); + +// bad_assert_copyable<N> is not needed for constant evaluation +// (and thus not instantiated) +template<typename T> consteval void assert_copyable() { T t; T t2 = t; } +using check = decltype(assert_copyable<N>()); +// FIXME: this should give an error because assert_copyable<N> is instantiated +// (because it is needed for constant evaluation), but the attempt to copy t is +// ill-formed. +} // namespace P1073R3 + Index: clang/test/CXX/expr/expr.const/p6-2a.cpp =================================================================== --- clang/test/CXX/expr/expr.const/p6-2a.cpp +++ clang/test/CXX/expr/expr.const/p6-2a.cpp @@ -41,3 +41,16 @@ } }; constexpr Temporary t = {3}; // expected-error {{must have constant destruction}} expected-note {{created here}} expected-note {{in call}} + +namespace P1073R3 { +consteval int f() { return 42; } // expected-note 3 {{declared here}} +consteval auto g() { return f; } +// FIXME: there should be no diagnostics associated with either h() or r. +consteval int h(int (*p)() = g()) { return p(); } // expected-error {{call to consteval function 'P1073R3::g' is not a constant expression}} \ + expected-note {{declared here}} \ + expected-note {{pointer to a consteval declaration is not a constant expression}} +constexpr int r = h(); // expected-note {{in the default initalizer of 'p'}} +constexpr auto e = g(); // expected-error {{call to consteval function 'P1073R3::g' is not a constant expression}} \ + expected-error {{constexpr variable 'e' must be initialized by a constant expression}} \ + expected-note 2 {{pointer to a consteval declaration is not a constant expression}} +} // namespace P1073R3
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits