[clang] 574e43d - [C23] Allow casting from a null pointer constant to nullptr_t (#133742)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 2 04:28:48 PDT 2025
Author: Aaron Ballman
Date: 2025-04-02T07:28:45-04:00
New Revision: 574e43dffd7a97d32f996df58b1787ad5158529c
URL: https://github.com/llvm/llvm-project/commit/574e43dffd7a97d32f996df58b1787ad5158529c
DIFF: https://github.com/llvm/llvm-project/commit/574e43dffd7a97d32f996df58b1787ad5158529c.diff
LOG: [C23] Allow casting from a null pointer constant to nullptr_t (#133742)
C23 allows a cast of a null pointer constant to nullptr_t. e.g.,
(nullptr_t)0 or (nullptr_t)(void *)0.
Fixes #133644
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaCast.cpp
clang/test/C/C23/n3042.c
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 35658d63be55c..eb2591b287c2c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -159,6 +159,8 @@ C23 Feature Support
which clarified that a compound literal used within a function prototype is
treated as if the compound literal were within the body rather than at file
scope.
+- Fixed a bug where you could not cast a null pointer constant to type
+ ``nullptr_t``. Fixes #GH133644.
Non-comprehensive list of changes in this release
-------------------------------------------------
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index a5dbc16eaea0b..2824dfce1572c 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -3091,10 +3091,10 @@ void CastOperation::CheckCStyleCast() {
return;
}
- // C23 6.5.4p4:
- // The type nullptr_t shall not be converted to any type other than void,
- // bool, or a pointer type. No type other than nullptr_t shall be converted
- // to nullptr_t.
+ // C23 6.5.5p4:
+ // ... The type nullptr_t shall not be converted to any type other than
+ // void, bool or a pointer type.If the target type is nullptr_t, the cast
+ // expression shall be a null pointer constant or have type nullptr_t.
if (SrcType->isNullPtrType()) {
// FIXME: 6.3.2.4p2 says that nullptr_t can be converted to itself, but
// 6.5.4p4 is a constraint check and nullptr_t is not void, bool, or a
@@ -3115,11 +3115,20 @@ void CastOperation::CheckCStyleCast() {
Self.CurFPFeatureOverrides());
}
}
+
if (DestType->isNullPtrType() && !SrcType->isNullPtrType()) {
- Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
- << /*type to nullptr*/ 1 << SrcType;
- SrcExpr = ExprError();
- return;
+ if (!SrcExpr.get()->isNullPointerConstant(Self.Context,
+ Expr::NPC_NeverValueDependent)) {
+ Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
+ << /*type to nullptr*/ 1 << SrcType;
+ SrcExpr = ExprError();
+ return;
+ }
+ // Need to convert the source from whatever its type is to a null pointer
+ // type first.
+ SrcExpr = ImplicitCastExpr::Create(Self.Context, DestType, CK_NullToPointer,
+ SrcExpr.get(), nullptr, VK_PRValue,
+ Self.CurFPFeatureOverrides());
}
if (DestType->isExtVectorType()) {
diff --git a/clang/test/C/C23/n3042.c b/clang/test/C/C23/n3042.c
index 99661b1fb39eb..fdcb48eb1322a 100644
--- a/clang/test/C/C23/n3042.c
+++ b/clang/test/C/C23/n3042.c
@@ -82,8 +82,6 @@ void test() {
(nullptr_t)12; // expected-error {{cannot cast an object of type 'int' to 'nullptr_t'}}
(float)null_val; // expected-error {{cannot cast an object of type 'nullptr_t' to 'float'}}
(float)nullptr; // expected-error {{cannot cast an object of type 'nullptr_t' to 'float'}}
- (nullptr_t)0; // expected-error {{cannot cast an object of type 'int' to 'nullptr_t'}}
- (nullptr_t)(void *)0; // expected-error {{cannot cast an object of type 'void *' to 'nullptr_t'}}
(nullptr_t)(int *)12; // expected-error {{cannot cast an object of type 'int *' to 'nullptr_t'}}
(void)null_val; // ok
@@ -93,6 +91,9 @@ void test() {
(int *)null_val; // ok
(int *)nullptr; // ok
(nullptr_t)nullptr; // ok
+ (nullptr_t)0; // ok
+ (nullptr_t)(void *)0; // ok
+ (nullptr_t)null_val; // ok
// Can it be converted to bool with the result false (this relies on Clang
// accepting additional kinds of constant expressions where an ICE is
More information about the cfe-commits
mailing list