Skip to content

Commit 6360cf5

Browse files
committed
Handle null pointer constants properly
1 parent 7ffaaf4 commit 6360cf5

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

clang/lib/Sema/SemaExpr.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9818,15 +9818,36 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
98189818
((getLangOpts().C23 && RHS.get()->getType()->isNullPtrType()) ||
98199819
RHS.get()->isNullPointerConstant(Context,
98209820
Expr::NPC_ValueDependentIsNull))) {
9821+
AssignConvertType Ret = Compatible;
98219822
if (Diagnose || ConvertRHS) {
98229823
CastKind Kind;
98239824
CXXCastPath Path;
98249825
CheckPointerConversion(RHS.get(), LHSType, Kind, Path,
98259826
/*IgnoreBaseAccess=*/false, Diagnose);
9827+
9828+
// If there is a conversion of some kind, check to see what kind of
9829+
// pointer conversion happened so we can diagnose a C++ compatibility
9830+
// diagnostic if the conversion is invalid. This only matters if the RHS
9831+
// is some kind of void pointer.
9832+
if (Kind != CK_NoOp && !getLangOpts().CPlusPlus) {
9833+
QualType CanRHS =
9834+
RHS.get()->getType().getCanonicalType().getUnqualifiedType();
9835+
QualType CanLHS = LHSType.getCanonicalType().getUnqualifiedType();
9836+
if (CanRHS->isVoidPointerType() && CanLHS->isPointerType()) {
9837+
Ret = checkPointerTypesForAssignment(*this, CanLHS, CanRHS,
9838+
RHS.get()->getExprLoc());
9839+
// Anything that's not considered perfectly compatible would be
9840+
// incompatible in C++.
9841+
if (Ret != Compatible)
9842+
Ret = CompatibleVoidPtrToNonVoidPtr;
9843+
}
9844+
}
9845+
9846+
98269847
if (ConvertRHS)
98279848
RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_PRValue, &Path);
98289849
}
9829-
return Compatible;
9850+
return Ret;
98309851
}
98319852
// C23 6.5.16.1p1: the left operand has type atomic, qualified, or
98329853
// unqualified bool, and the right operand is a pointer or its type is
@@ -13946,10 +13967,8 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
1394613967
LHSType->isObjCObjectPointerType())))
1394713968
ConvTy = Compatible;
1394813969

13949-
if (ConvTy == Compatible &&
13950-
LHSType->isObjCObjectType())
13951-
Diag(Loc, diag::err_objc_object_assignment)
13952-
<< LHSType;
13970+
if (IsAssignConvertCompatible(ConvTy) && LHSType->isObjCObjectType())
13971+
Diag(Loc, diag::err_objc_object_assignment) << LHSType;
1395313972

1395413973
// If the RHS is a unary plus or minus, check to see if they = and + are
1395513974
// right next to each other. If so, the user may have typo'd "x =+ 4"
@@ -13971,7 +13990,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
1397113990
}
1397213991
}
1397313992

13974-
if (ConvTy == Compatible) {
13993+
if (IsAssignConvertCompatible(ConvTy)) {
1397513994
if (LHSType.getObjCLifetime() == Qualifiers::OCL_Strong) {
1397613995
// Warn about retain cycles where a block captures the LHS, but
1397713996
// not if the LHS is a simple variable into which the block is

0 commit comments

Comments
 (0)