Author: offsetof Date: 2024-04-29T17:23:50+04:00 New Revision: caa902613a96f63c3855b3a0bcd82d1b1db49408
URL: https://github.com/llvm/llvm-project/commit/caa902613a96f63c3855b3a0bcd82d1b1db49408 DIFF: https://github.com/llvm/llvm-project/commit/caa902613a96f63c3855b3a0bcd82d1b1db49408.diff LOG: [clang] Allow constexpr cast from `void*` in more cases (#89484) [[expr.const]/5.14](https://eel.is/c++draft/expr.const#5.14) says that constexpr cast from <code>*cv* void\*</code> to `T*` is OK if the pointee type is similar to `T`, but Clang currently only permits the conversion if the types are the same except top-level cv-qualifiers. This patch also allows casting `(void*)nullptr`, implementing the resolution of [CWG2819](https://cplusplus.github.io/CWG/issues/2819). --------- Co-authored-by: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Added: Modified: clang/lib/AST/ExprConstant.cpp clang/test/CXX/drs/dr25xx.cpp clang/test/CXX/drs/dr28xx.cpp clang/test/CXX/expr/expr.const/p5-26.cpp clang/www/cxx_dr_status.html clang/www/make_cxx_dr_status Removed: ################################################################################ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index ea3e7304a7423c..71b5f91b4d2591 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9237,9 +9237,10 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) { bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid && !Result.IsNullPtr; bool VoidPtrCastMaybeOK = - HasValidResult && - Info.Ctx.hasSameUnqualifiedType(Result.Designator.getType(Info.Ctx), - E->getType()->getPointeeType()); + Result.IsNullPtr || + (HasValidResult && + Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx), + E->getType()->getPointeeType())); // 1. We'll allow it in std::allocator::allocate, and anything which that // calls. // 2. HACK 2022-03-28: Work around an issue with libstdc++'s diff --git a/clang/test/CXX/drs/dr25xx.cpp b/clang/test/CXX/drs/dr25xx.cpp index 481ae09cdb77ea..8bca58f44944f7 100644 --- a/clang/test/CXX/drs/dr25xx.cpp +++ b/clang/test/CXX/drs/dr25xx.cpp @@ -130,7 +130,7 @@ struct D3 : B { #endif #if __cplusplus >= 202302L -namespace cwg2561 { // cwg2561: no +namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18 struct C { constexpr C(auto) { } }; diff --git a/clang/test/CXX/drs/dr28xx.cpp b/clang/test/CXX/drs/dr28xx.cpp index 1967e8b751db2d..be35d366bdd614 100644 --- a/clang/test/CXX/drs/dr28xx.cpp +++ b/clang/test/CXX/drs/dr28xx.cpp @@ -10,6 +10,14 @@ // expected-no-diagnostics #endif +namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01 +#if __cpp_constexpr >= 202306L + constexpr void* p = nullptr; + constexpr int* q = static_cast<int*>(p); + static_assert(q == nullptr); +#endif +} + namespace cwg2847 { // cwg2847: 19 review 2024-03-01 #if __cplusplus >= 202002L @@ -59,7 +67,7 @@ void B<int>::g() requires true; } // namespace cwg2847 -namespace cwg2858 { // cwg2858: 19 +namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05 #if __cplusplus > 202302L diff --git a/clang/test/CXX/expr/expr.const/p5-26.cpp b/clang/test/CXX/expr/expr.const/p5-26.cpp index 3624b1e5a3e3df..7513b11c09aa01 100644 --- a/clang/test/CXX/expr/expr.const/p5-26.cpp +++ b/clang/test/CXX/expr/expr.const/p5-26.cpp @@ -37,3 +37,10 @@ void err() { // cxx23-note {{cast from 'void *' is not allowed in a constant expression in C++ standards before C++2c}} \ // cxx26-note {{cast from 'void *' is not allowed in a constant expression because the pointed object type 'T' is not similar to the target type 'S'}} } + +int* p; +constexpr int** pp = &p; +constexpr void* vp = pp; +constexpr auto cvp = static_cast<const int* volatile*>(vp); +// cxx23-error@-1 {{constant expression}} +// cxx23-note@-2 {{cast from 'void *' is not allowed in a constant expression}} diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 19d29cb55d6ed0..875521bd505d5b 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -1433,11 +1433,11 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td>Is indirection through a null pointer undefined behavior?</td> <td class="unknown" align="center">Unknown</td> </tr> - <tr id="233"> + <tr class="open" id="233"> <td><a href="https://cplusplus.github.io/CWG/issues/233.html">233</a></td> <td>tentatively ready</td> <td>References vs pointers in UDC overload resolution</td> - <td class="unknown" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="234"> <td><a href="https://cplusplus.github.io/CWG/issues/234.html">234</a></td> @@ -15170,11 +15170,11 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td>Parameter type determination in a <I>requirement-parameter-list</I></td> <td class="unknown" align="center">Unknown</td> </tr> - <tr id="2561"> + <tr class="open" id="2561"> <td><a href="https://cplusplus.github.io/CWG/issues/2561.html">2561</a></td> <td>tentatively ready</td> <td>Conversion to function pointer for lambda with explicit object parameter</td> - <td class="none" align="center">No</td> + <td title="Clang does not implement 2024-03-18 resolution" align="center">Not Resolved*</td> </tr> <tr class="open" id="2562"> <td><a href="https://cplusplus.github.io/CWG/issues/2562.html">2562</a></td> @@ -15332,11 +15332,11 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td>Visible side effects and initial value of an object</td> <td align="center">Not resolved</td> </tr> - <tr id="2588"> + <tr class="open" id="2588"> <td><a href="https://cplusplus.github.io/CWG/issues/2588.html">2588</a></td> <td>tentatively ready</td> <td>friend declarations and module linkage</td> - <td class="unknown" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="2589"> <td><a href="https://cplusplus.github.io/CWG/issues/2589.html">2589</a></td> @@ -16172,11 +16172,11 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td>Importing header units synthesized from source files</td> <td align="center">Not resolved</td> </tr> - <tr id="2728"> + <tr class="open" id="2728"> <td><a href="https://cplusplus.github.io/CWG/issues/2728.html">2728</a></td> <td>tentatively ready</td> <td>Evaluation of conversions in a <I>delete-expression</I></td> - <td class="unknown" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="2729"> <td><a href="https://cplusplus.github.io/CWG/issues/2729.html">2729</a></td> @@ -16713,17 +16713,17 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td>sizeof(abstract class) is underspecified</td> <td align="center">Not resolved</td> </tr> - <tr id="2818"> + <tr class="open" id="2818"> <td><a href="https://cplusplus.github.io/CWG/issues/2818.html">2818</a></td> <td>tentatively ready</td> <td>Use of predefined reserved identifiers</td> - <td class="unknown" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2819"> + <tr class="open" id="2819"> <td><a href="https://cplusplus.github.io/CWG/issues/2819.html">2819</a></td> <td>tentatively ready</td> <td>Cast from null pointer value in a constant expression</td> - <td class="unknown" align="center">Unknown</td> + <td title="Clang 19 implements 2023-12-01 resolution" align="center">Not Resolved*</td> </tr> <tr id="2820"> <td><a href="https://cplusplus.github.io/CWG/issues/2820.html">2820</a></td> @@ -16953,17 +16953,17 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td>Argument-dependent lookup with incomplete class types</td> <td class="unknown" align="center">Unknown</td> </tr> - <tr id="2858"> + <tr class="open" id="2858"> <td><a href="https://cplusplus.github.io/CWG/issues/2858.html">2858</a></td> <td>tentatively ready</td> <td>Declarative <I>nested-name-specifier</I>s and <I>pack-index-specifier</I>s</td> - <td class="unreleased" align="center">Clang 19</td> + <td title="Clang 19 implements 2024-04-05 resolution" align="center">Not Resolved*</td> </tr> - <tr id="2859"> + <tr class="open" id="2859"> <td><a href="https://cplusplus.github.io/CWG/issues/2859.html">2859</a></td> <td>tentatively ready</td> <td>Value-initialization with multiple default constructors</td> - <td class="unknown" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr id="2860"> <td><a href="https://cplusplus.github.io/CWG/issues/2860.html">2860</a></td> @@ -16971,29 +16971,29 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td>Remove and fix the term "vacuous initialization"</td> <td class="unknown" align="center">Unknown</td> </tr> - <tr id="2861"> + <tr class="open" id="2861"> <td><a href="https://cplusplus.github.io/CWG/issues/2861.html">2861</a></td> <td>tentatively ready</td> <td><TT>dynamic_cast</TT> on bad pointer value</td> - <td class="unknown" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2862"> + <tr class="open" id="2862"> <td><a href="https://cplusplus.github.io/CWG/issues/2862.html">2862</a></td> <td>tentatively ready</td> <td>Unclear boundaries of template declarations</td> - <td class="unknown" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2863"> + <tr class="open" id="2863"> <td><a href="https://cplusplus.github.io/CWG/issues/2863.html">2863</a></td> <td>tentatively ready</td> <td>Unclear synchronization requirements for object lifetime rules</td> - <td class="unknown" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> - <tr id="2864"> + <tr class="open" id="2864"> <td><a href="https://cplusplus.github.io/CWG/issues/2864.html">2864</a></td> <td>tentatively ready</td> <td>Narrowing floating-point conversions</td> - <td class="unknown" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="2865"> <td><a href="https://cplusplus.github.io/CWG/issues/2865.html">2865</a></td> @@ -17031,11 +17031,11 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td>Combining absent <I>encoding-prefix</I>es</td> <td align="center">Not resolved</td> </tr> - <tr id="2871"> + <tr class="open" id="2871"> <td><a href="https://cplusplus.github.io/CWG/issues/2871.html">2871</a></td> <td>tentatively ready</td> <td>User-declared constructor templates inhibiting default constructors</td> - <td class="unknown" align="center">Unknown</td> + <td align="center">Not resolved</td> </tr> <tr class="open" id="2872"> <td><a href="https://cplusplus.github.io/CWG/issues/2872.html">2872</a></td> @@ -17096,6 +17096,36 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td>open</td> <td>Type restrictions for the explicit object parameter of a lambda</td> <td align="center">Not resolved</td> + </tr> + <tr class="open" id="2882"> + <td><a href="https://cplusplus.github.io/CWG/issues/2882.html">2882</a></td> + <td>open</td> + <td>Unclear treatment of conversion to <TT>void</TT></td> + <td align="center">Not resolved</td> + </tr> + <tr class="open" id="2883"> + <td><a href="https://cplusplus.github.io/CWG/issues/2883.html">2883</a></td> + <td>open</td> + <td>Definition of "odr-usable" ignores lambda scopes</td> + <td align="center">Not resolved</td> + </tr> + <tr class="open" id="2884"> + <td><a href="https://cplusplus.github.io/CWG/issues/2884.html">2884</a></td> + <td>open</td> + <td>Qualified declarations of partial specializations</td> + <td align="center">Not resolved</td> + </tr> + <tr class="open" id="2885"> + <td><a href="https://cplusplus.github.io/CWG/issues/2885.html">2885</a></td> + <td>open</td> + <td>Non-eligible trivial default constructors</td> + <td align="center">Not resolved</td> + </tr> + <tr class="open" id="2886"> + <td><a href="https://cplusplus.github.io/CWG/issues/2886.html">2886</a></td> + <td>open</td> + <td>Temporaries and trivial potentially-throwing special member functions</td> + <td align="center">Not resolved</td> </tr></table> </div> diff --git a/clang/www/make_cxx_dr_status b/clang/www/make_cxx_dr_status index 57f1dc86fd1251..47c8b3bae4a179 100755 --- a/clang/www/make_cxx_dr_status +++ b/clang/www/make_cxx_dr_status @@ -236,7 +236,7 @@ for dr in drs: avail = 'Extension' avail_style = '' - elif dr.status in ('open', 'drafting', 'review'): + elif dr.status in ('open', 'drafting', 'review', 'tentatively ready'): row_style = ' class="open"' try: avail, avail_style, unresolved_status = availability(dr.issue) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits