Skip to content

Commit 5ad66ec

Browse files
committed
[C23] Allow casting from a null pointer constant to nullptr_t
C23 allows a cast of a null pointer constant to nullptr_t. e.g., (nullptr_t)0 or (nullptr_t)(void *)0. Fixes #133644
1 parent 8d69e95 commit 5ad66ec

File tree

3 files changed

+23
-7
lines changed

3 files changed

+23
-7
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ C23 Feature Support
159159
which clarified that a compound literal used within a function prototype is
160160
treated as if the compound literal were within the body rather than at file
161161
scope.
162+
- Fixed a bug where you could not cast a null pointer constant to type
163+
``nullptr_t``. Fixes #GH133644.
162164

163165
Non-comprehensive list of changes in this release
164166
-------------------------------------------------

clang/lib/Sema/SemaCast.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3115,11 +3115,24 @@ void CastOperation::CheckCStyleCast() {
31153115
Self.CurFPFeatureOverrides());
31163116
}
31173117
}
3118-
if (DestType->isNullPtrType() && !SrcType->isNullPtrType()) {
3119-
Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3120-
<< /*type to nullptr*/ 1 << SrcType;
3121-
SrcExpr = ExprError();
3122-
return;
3118+
// C23 6.3.2.4p2: a null pointer constant or value of type nullptr_t may be
3119+
// converted to nullptr_t.
3120+
if (DestType->isNullPtrType()) {
3121+
if (!SrcType->isNullPtrType() &&
3122+
!SrcExpr.get()->isNullPointerConstant(Self.Context,
3123+
Expr::NPC_NeverValueDependent)) {
3124+
Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3125+
<< /*type to nullptr*/ 1 << SrcType;
3126+
SrcExpr = ExprError();
3127+
return;
3128+
}
3129+
if (!SrcType->isNullPtrType()) {
3130+
// Need to convert the source from whatever its type is to a null pointer
3131+
// type first.
3132+
SrcExpr = ImplicitCastExpr::Create(
3133+
Self.Context, DestType, CK_NullToPointer, SrcExpr.get(), nullptr,
3134+
VK_PRValue, Self.CurFPFeatureOverrides());
3135+
}
31233136
}
31243137

31253138
if (DestType->isExtVectorType()) {

clang/test/C/C23/n3042.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,6 @@ void test() {
8282
(nullptr_t)12; // expected-error {{cannot cast an object of type 'int' to 'nullptr_t'}}
8383
(float)null_val; // expected-error {{cannot cast an object of type 'nullptr_t' to 'float'}}
8484
(float)nullptr; // expected-error {{cannot cast an object of type 'nullptr_t' to 'float'}}
85-
(nullptr_t)0; // expected-error {{cannot cast an object of type 'int' to 'nullptr_t'}}
86-
(nullptr_t)(void *)0; // expected-error {{cannot cast an object of type 'void *' to 'nullptr_t'}}
8785
(nullptr_t)(int *)12; // expected-error {{cannot cast an object of type 'int *' to 'nullptr_t'}}
8886

8987
(void)null_val; // ok
@@ -93,6 +91,9 @@ void test() {
9391
(int *)null_val; // ok
9492
(int *)nullptr; // ok
9593
(nullptr_t)nullptr; // ok
94+
(nullptr_t)0; // ok
95+
(nullptr_t)(void *)0; // ok
96+
(nullptr_t)null_val; // ok
9697

9798
// Can it be converted to bool with the result false (this relies on Clang
9899
// accepting additional kinds of constant expressions where an ICE is

0 commit comments

Comments
 (0)