aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2023-05-03 14:06:04 -0400
committerAaron Ballman <aaron@aaronballman.com>2023-05-03 14:50:15 -0400
commit9bb28a18d962e8f6e3fa8f48bd2c6dc183154d26 (patch)
treea957df9e5efdf709408df48bf385ceaf7a9f4987 /clang/lib
parent791b0fd02668fd0fcf07788d4e16bb468434f4bf (diff)
downloadllvm-9bb28a18d962e8f6e3fa8f48bd2c6dc183154d26.zip
llvm-9bb28a18d962e8f6e3fa8f48bd2c6dc183154d26.tar.gz
llvm-9bb28a18d962e8f6e3fa8f48bd2c6dc183154d26.tar.bz2
[C2x] Update 'nullptr' implementation based on CD comments
We filed some CD ballot comments which WG14 considered during the ballot comment resolution meetings in Jan and Feb 2023, and this updates our implementation based on the decisions reached. Those decisions were (paraphrased for brevity): US 9-034 (REJECTED) allow (void *)nullptr to be a null pointer constant US 10-035 (ACCEPTED) accept the following code, as in C++: void func(nullptr_t); func(0); US 22-058 (REJECTED) accept the following code, as in C++: nullptr_t val; (void)(1 ? val : 0); (void)(1 ? nullptr : 0); US 23-062 (REJECTED) reject the following code, as in C++: nullptr_t val; bool b1 = val; bool b2 = nullptr; US 24-061 (ACCEPTED) accept the following code, as in C++: nullptr_t val; val = 0; US 21-068 (ACCEPTED) accept the following code, as in C++: (nullptr_t)nullptr; GB-071 (ACCEPTED) accept the following code, as in C++: nullptr_t val; (void)(val == nullptr); This patch updates the implementation as appropriate, but is primarily focused around US 10-035, US 24-061, and US 23-062 in terms of functional changes. Differential Revision: https://reviews.llvm.org/D148800
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp36
1 files changed, 33 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8789e4c..048f38c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10118,6 +10118,15 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
return Incompatible;
}
+ // Conversion to nullptr_t (C2x only)
+ if (getLangOpts().C2x && LHSType->isNullPtrType() &&
+ RHS.get()->isNullPointerConstant(Context,
+ Expr::NPC_ValueDependentIsNull)) {
+ // null -> nullptr_t
+ Kind = CK_NullToPointer;
+ return Compatible;
+ }
+
// Conversions from pointers that are not covered by the above.
if (isa<PointerType>(RHSType)) {
// T* -> _Bool
@@ -10335,12 +10344,13 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
QualType LHSTypeAfterConversion = LHSType.getAtomicUnqualifiedType();
// C99 6.5.16.1p1: the left operand is a pointer and the right is
- // a null pointer constant.
+ // a null pointer constant <C2x>or its type is nullptr_t;</C2x>.
if ((LHSTypeAfterConversion->isPointerType() ||
LHSTypeAfterConversion->isObjCObjectPointerType() ||
LHSTypeAfterConversion->isBlockPointerType()) &&
- RHS.get()->isNullPointerConstant(Context,
- Expr::NPC_ValueDependentIsNull)) {
+ ((getLangOpts().C2x && RHS.get()->getType()->isNullPtrType()) ||
+ RHS.get()->isNullPointerConstant(Context,
+ Expr::NPC_ValueDependentIsNull))) {
if (Diagnose || ConvertRHS) {
CastKind Kind;
CXXCastPath Path;
@@ -10351,6 +10361,26 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
}
return Compatible;
}
+ // C2x 6.5.16.1p1: the left operand has type atomic, qualified, or
+ // unqualified bool, and the right operand is a pointer or its type is
+ // nullptr_t.
+ if (getLangOpts().C2x && LHSType->isBooleanType() &&
+ RHS.get()->getType()->isNullPtrType()) {
+ // NB: T* -> _Bool is handled in CheckAssignmentConstraints, this only
+ // only handles nullptr -> _Bool due to needing an extra conversion
+ // step.
+ // We model this by converting from nullptr -> void * and then let the
+ // conversion from void * -> _Bool happen naturally.
+ if (Diagnose || ConvertRHS) {
+ CastKind Kind;
+ CXXCastPath Path;
+ CheckPointerConversion(RHS.get(), Context.VoidPtrTy, Kind, Path,
+ /*IgnoreBaseAccess=*/false, Diagnose);
+ if (ConvertRHS)
+ RHS = ImpCastExprToType(RHS.get(), Context.VoidPtrTy, Kind, VK_PRValue,
+ &Path);
+ }
+ }
// OpenCL queue_t type assignment.
if (LHSType->isQueueT() && RHS.get()->isNullPointerConstant(