Skip to content

Commit caa9026

Browse files
offsetofEndilll
andauthored
[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 <[email protected]>
1 parent e57b872 commit caa9026

File tree

6 files changed

+78
-32
lines changed

6 files changed

+78
-32
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9237,9 +9237,10 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
92379237
bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid &&
92389238
!Result.IsNullPtr;
92399239
bool VoidPtrCastMaybeOK =
9240-
HasValidResult &&
9241-
Info.Ctx.hasSameUnqualifiedType(Result.Designator.getType(Info.Ctx),
9242-
E->getType()->getPointeeType());
9240+
Result.IsNullPtr ||
9241+
(HasValidResult &&
9242+
Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx),
9243+
E->getType()->getPointeeType()));
92439244
// 1. We'll allow it in std::allocator::allocate, and anything which that
92449245
// calls.
92459246
// 2. HACK 2022-03-28: Work around an issue with libstdc++'s

clang/test/CXX/drs/dr25xx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ struct D3 : B {
130130
#endif
131131

132132
#if __cplusplus >= 202302L
133-
namespace cwg2561 { // cwg2561: no
133+
namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18
134134
struct C {
135135
constexpr C(auto) { }
136136
};

clang/test/CXX/drs/dr28xx.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@
1010
// expected-no-diagnostics
1111
#endif
1212

13+
namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01
14+
#if __cpp_constexpr >= 202306L
15+
constexpr void* p = nullptr;
16+
constexpr int* q = static_cast<int*>(p);
17+
static_assert(q == nullptr);
18+
#endif
19+
}
20+
1321
namespace cwg2847 { // cwg2847: 19 review 2024-03-01
1422

1523
#if __cplusplus >= 202002L
@@ -59,7 +67,7 @@ void B<int>::g() requires true;
5967

6068
} // namespace cwg2847
6169

62-
namespace cwg2858 { // cwg2858: 19
70+
namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
6371

6472
#if __cplusplus > 202302L
6573

clang/test/CXX/expr/expr.const/p5-26.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,10 @@ void err() {
3737
// cxx23-note {{cast from 'void *' is not allowed in a constant expression in C++ standards before C++2c}} \
3838
// 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'}}
3939
}
40+
41+
int* p;
42+
constexpr int** pp = &p;
43+
constexpr void* vp = pp;
44+
constexpr auto cvp = static_cast<const int* volatile*>(vp);
45+
// cxx23-error@-1 {{constant expression}}
46+
// cxx23-note@-2 {{cast from 'void *' is not allowed in a constant expression}}

clang/www/cxx_dr_status.html

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,11 +1433,11 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
14331433
<td>Is indirection through a null pointer undefined behavior?</td>
14341434
<td class="unknown" align="center">Unknown</td>
14351435
</tr>
1436-
<tr id="233">
1436+
<tr class="open" id="233">
14371437
<td><a href="https://cplusplus.github.io/CWG/issues/233.html">233</a></td>
14381438
<td>tentatively ready</td>
14391439
<td>References vs pointers in UDC overload resolution</td>
1440-
<td class="unknown" align="center">Unknown</td>
1440+
<td align="center">Not resolved</td>
14411441
</tr>
14421442
<tr id="234">
14431443
<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>
1517015170
<td>Parameter type determination in a <I>requirement-parameter-list</I></td>
1517115171
<td class="unknown" align="center">Unknown</td>
1517215172
</tr>
15173-
<tr id="2561">
15173+
<tr class="open" id="2561">
1517415174
<td><a href="https://cplusplus.github.io/CWG/issues/2561.html">2561</a></td>
1517515175
<td>tentatively ready</td>
1517615176
<td>Conversion to function pointer for lambda with explicit object parameter</td>
15177-
<td class="none" align="center">No</td>
15177+
<td title="Clang does not implement 2024-03-18 resolution" align="center">Not Resolved*</td>
1517815178
</tr>
1517915179
<tr class="open" id="2562">
1518015180
<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>
1533215332
<td>Visible side effects and initial value of an object</td>
1533315333
<td align="center">Not resolved</td>
1533415334
</tr>
15335-
<tr id="2588">
15335+
<tr class="open" id="2588">
1533615336
<td><a href="https://cplusplus.github.io/CWG/issues/2588.html">2588</a></td>
1533715337
<td>tentatively ready</td>
1533815338
<td>friend declarations and module linkage</td>
15339-
<td class="unknown" align="center">Unknown</td>
15339+
<td align="center">Not resolved</td>
1534015340
</tr>
1534115341
<tr class="open" id="2589">
1534215342
<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>
1617216172
<td>Importing header units synthesized from source files</td>
1617316173
<td align="center">Not resolved</td>
1617416174
</tr>
16175-
<tr id="2728">
16175+
<tr class="open" id="2728">
1617616176
<td><a href="https://cplusplus.github.io/CWG/issues/2728.html">2728</a></td>
1617716177
<td>tentatively ready</td>
1617816178
<td>Evaluation of conversions in a <I>delete-expression</I></td>
16179-
<td class="unknown" align="center">Unknown</td>
16179+
<td align="center">Not resolved</td>
1618016180
</tr>
1618116181
<tr id="2729">
1618216182
<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>
1671316713
<td>sizeof(abstract class) is underspecified</td>
1671416714
<td align="center">Not resolved</td>
1671516715
</tr>
16716-
<tr id="2818">
16716+
<tr class="open" id="2818">
1671716717
<td><a href="https://cplusplus.github.io/CWG/issues/2818.html">2818</a></td>
1671816718
<td>tentatively ready</td>
1671916719
<td>Use of predefined reserved identifiers</td>
16720-
<td class="unknown" align="center">Unknown</td>
16720+
<td align="center">Not resolved</td>
1672116721
</tr>
16722-
<tr id="2819">
16722+
<tr class="open" id="2819">
1672316723
<td><a href="https://cplusplus.github.io/CWG/issues/2819.html">2819</a></td>
1672416724
<td>tentatively ready</td>
1672516725
<td>Cast from null pointer value in a constant expression</td>
16726-
<td class="unknown" align="center">Unknown</td>
16726+
<td title="Clang 19 implements 2023-12-01 resolution" align="center">Not Resolved*</td>
1672716727
</tr>
1672816728
<tr id="2820">
1672916729
<td><a href="https://cplusplus.github.io/CWG/issues/2820.html">2820</a></td>
@@ -16953,47 +16953,47 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
1695316953
<td>Argument-dependent lookup with incomplete class types</td>
1695416954
<td class="unknown" align="center">Unknown</td>
1695516955
</tr>
16956-
<tr id="2858">
16956+
<tr class="open" id="2858">
1695716957
<td><a href="https://cplusplus.github.io/CWG/issues/2858.html">2858</a></td>
1695816958
<td>tentatively ready</td>
1695916959
<td>Declarative <I>nested-name-specifier</I>s and <I>pack-index-specifier</I>s</td>
16960-
<td class="unreleased" align="center">Clang 19</td>
16960+
<td title="Clang 19 implements 2024-04-05 resolution" align="center">Not Resolved*</td>
1696116961
</tr>
16962-
<tr id="2859">
16962+
<tr class="open" id="2859">
1696316963
<td><a href="https://cplusplus.github.io/CWG/issues/2859.html">2859</a></td>
1696416964
<td>tentatively ready</td>
1696516965
<td>Value-initialization with multiple default constructors</td>
16966-
<td class="unknown" align="center">Unknown</td>
16966+
<td align="center">Not resolved</td>
1696716967
</tr>
1696816968
<tr id="2860">
1696916969
<td><a href="https://cplusplus.github.io/CWG/issues/2860.html">2860</a></td>
1697016970
<td>dup</td>
1697116971
<td>Remove and fix the term "vacuous initialization"</td>
1697216972
<td class="unknown" align="center">Unknown</td>
1697316973
</tr>
16974-
<tr id="2861">
16974+
<tr class="open" id="2861">
1697516975
<td><a href="https://cplusplus.github.io/CWG/issues/2861.html">2861</a></td>
1697616976
<td>tentatively ready</td>
1697716977
<td><TT>dynamic_cast</TT> on bad pointer value</td>
16978-
<td class="unknown" align="center">Unknown</td>
16978+
<td align="center">Not resolved</td>
1697916979
</tr>
16980-
<tr id="2862">
16980+
<tr class="open" id="2862">
1698116981
<td><a href="https://cplusplus.github.io/CWG/issues/2862.html">2862</a></td>
1698216982
<td>tentatively ready</td>
1698316983
<td>Unclear boundaries of template declarations</td>
16984-
<td class="unknown" align="center">Unknown</td>
16984+
<td align="center">Not resolved</td>
1698516985
</tr>
16986-
<tr id="2863">
16986+
<tr class="open" id="2863">
1698716987
<td><a href="https://cplusplus.github.io/CWG/issues/2863.html">2863</a></td>
1698816988
<td>tentatively ready</td>
1698916989
<td>Unclear synchronization requirements for object lifetime rules</td>
16990-
<td class="unknown" align="center">Unknown</td>
16990+
<td align="center">Not resolved</td>
1699116991
</tr>
16992-
<tr id="2864">
16992+
<tr class="open" id="2864">
1699316993
<td><a href="https://cplusplus.github.io/CWG/issues/2864.html">2864</a></td>
1699416994
<td>tentatively ready</td>
1699516995
<td>Narrowing floating-point conversions</td>
16996-
<td class="unknown" align="center">Unknown</td>
16996+
<td align="center">Not resolved</td>
1699716997
</tr>
1699816998
<tr class="open" id="2865">
1699916999
<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>
1703117031
<td>Combining absent <I>encoding-prefix</I>es</td>
1703217032
<td align="center">Not resolved</td>
1703317033
</tr>
17034-
<tr id="2871">
17034+
<tr class="open" id="2871">
1703517035
<td><a href="https://cplusplus.github.io/CWG/issues/2871.html">2871</a></td>
1703617036
<td>tentatively ready</td>
1703717037
<td>User-declared constructor templates inhibiting default constructors</td>
17038-
<td class="unknown" align="center">Unknown</td>
17038+
<td align="center">Not resolved</td>
1703917039
</tr>
1704017040
<tr class="open" id="2872">
1704117041
<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>
1709617096
<td>open</td>
1709717097
<td>Type restrictions for the explicit object parameter of a lambda</td>
1709817098
<td align="center">Not resolved</td>
17099+
</tr>
17100+
<tr class="open" id="2882">
17101+
<td><a href="https://cplusplus.github.io/CWG/issues/2882.html">2882</a></td>
17102+
<td>open</td>
17103+
<td>Unclear treatment of conversion to <TT>void</TT></td>
17104+
<td align="center">Not resolved</td>
17105+
</tr>
17106+
<tr class="open" id="2883">
17107+
<td><a href="https://cplusplus.github.io/CWG/issues/2883.html">2883</a></td>
17108+
<td>open</td>
17109+
<td>Definition of "odr-usable" ignores lambda scopes</td>
17110+
<td align="center">Not resolved</td>
17111+
</tr>
17112+
<tr class="open" id="2884">
17113+
<td><a href="https://cplusplus.github.io/CWG/issues/2884.html">2884</a></td>
17114+
<td>open</td>
17115+
<td>Qualified declarations of partial specializations</td>
17116+
<td align="center">Not resolved</td>
17117+
</tr>
17118+
<tr class="open" id="2885">
17119+
<td><a href="https://cplusplus.github.io/CWG/issues/2885.html">2885</a></td>
17120+
<td>open</td>
17121+
<td>Non-eligible trivial default constructors</td>
17122+
<td align="center">Not resolved</td>
17123+
</tr>
17124+
<tr class="open" id="2886">
17125+
<td><a href="https://cplusplus.github.io/CWG/issues/2886.html">2886</a></td>
17126+
<td>open</td>
17127+
<td>Temporaries and trivial potentially-throwing special member functions</td>
17128+
<td align="center">Not resolved</td>
1709917129
</tr></table>
1710017130

1710117131
</div>

clang/www/make_cxx_dr_status

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ for dr in drs:
236236
avail = 'Extension'
237237
avail_style = ''
238238

239-
elif dr.status in ('open', 'drafting', 'review'):
239+
elif dr.status in ('open', 'drafting', 'review', 'tentatively ready'):
240240
row_style = ' class="open"'
241241
try:
242242
avail, avail_style, unresolved_status = availability(dr.issue)

0 commit comments

Comments
 (0)