summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard@metafoo.co.uk>2019-12-16 17:40:03 -0800
committerRichard Smith <richard@metafoo.co.uk>2019-12-16 17:49:45 -0800
commitf495de43bd5da50286da6020e508d106cfc60f57 (patch)
treeae8d1dfe2648a19913a6750fd2aeebe54b4d6c1b /clang/lib/Sema/SemaExpr.cpp
parent4e9f1379b9cd7ddce8cf182707e976ebceb72b05 (diff)
downloadbcm5719-llvm-f495de43bd5da50286da6020e508d106cfc60f57.tar.gz
bcm5719-llvm-f495de43bd5da50286da6020e508d106cfc60f57.zip
[c++20] P1959R0: Remove support for std::*_equality.
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp57
1 files changed, 35 insertions, 22 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 86c3684d03f..15e86ba8e8d 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10648,9 +10648,11 @@ static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S,
return QualType();
if (Type.isNull())
return S.InvalidOperands(Loc, LHS, RHS);
- assert(Type->isArithmeticType() || Type->isEnumeralType());
- // FIXME: Reject complex types, consistent with P1959R0.
+ Optional<ComparisonCategoryType> CCT =
+ getComparisonCategoryForBuiltinCmp(Type);
+ if (!CCT)
+ return S.InvalidOperands(Loc, LHS, RHS);
bool HasNarrowing = checkThreeWayNarrowingConversion(
S, Type, LHS.get(), LHSType, LHS.get()->getBeginLoc());
@@ -10662,8 +10664,7 @@ static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S,
assert(!Type.isNull() && "composite type for <=> has not been set");
return S.CheckComparisonCategoryType(
- *getComparisonCategoryForBuiltinCmp(Type), Loc,
- Sema::ComparisonCategoryUsage::OperatorInExpression);
+ *CCT, Loc, Sema::ComparisonCategoryUsage::OperatorInExpression);
}
static QualType checkArithmeticOrEnumeralCompare(Sema &S, ExprResult &LHS,
@@ -10725,6 +10726,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
BinaryOperatorKind Opc) {
bool IsRelational = BinaryOperator::isRelationalOp(Opc);
bool IsThreeWay = Opc == BO_Cmp;
+ bool IsOrdered = IsRelational || IsThreeWay;
auto IsAnyPointerType = [](ExprResult E) {
QualType Ty = E.get()->getType();
return Ty->isPointerType() || Ty->isMemberPointerType();
@@ -10794,16 +10796,19 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
if (CompositeTy->isPointerType() && LHSIsNull != RHSIsNull) {
// P0946R0: Comparisons between a null pointer constant and an object
- // pointer result in std::strong_equality
- // FIXME: Reject this, consistent with P1959R0 + P0946R0.
- CCT = ComparisonCategoryType::StrongEquality;
+ // pointer result in std::strong_equality, which is ill-formed under
+ // P1959R0.
+ Diag(Loc, diag::err_typecheck_three_way_comparison_of_pointer_and_zero)
+ << (LHSIsNull ? LHS.get()->getSourceRange()
+ : RHS.get()->getSourceRange());
+ return QualType();
}
return CheckComparisonCategoryType(
*CCT, Loc, ComparisonCategoryUsage::OperatorInExpression);
};
- if (!IsRelational && LHSIsNull != RHSIsNull) {
+ if (!IsOrdered && LHSIsNull != RHSIsNull) {
bool IsEquality = Opc == BO_EQ;
if (RHSIsNull)
DiagnoseAlwaysNonNullPointer(LHS.get(), RHSNullKind, IsEquality,
@@ -10822,7 +10827,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
// but we allow it as an extension.
// FIXME: If we really want to allow this, should it be part of composite
// pointer type computation so it works in conditionals too?
- if (!IsRelational &&
+ if (!IsOrdered &&
((LHSType->isFunctionPointerType() && RHSType->isVoidPointerType()) ||
(RHSType->isFunctionPointerType() && LHSType->isVoidPointerType()))) {
// This is a gcc extension compatibility comparison.
@@ -10847,8 +10852,11 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
// C++ [expr.rel]p2:
// If both operands are pointers, [...] bring them to their composite
// pointer type.
+ // For <=>, the only valid non-pointer types are arrays and functions, and
+ // we already decayed those, so this is really the same as the relational
+ // comparison rule.
if ((int)LHSType->isPointerType() + (int)RHSType->isPointerType() >=
- (IsRelational ? 2 : 1) &&
+ (IsOrdered ? 2 : 1) &&
(!LangOpts.ObjCAutoRefCount || !(LHSType->isObjCObjectPointerType() ||
RHSType->isObjCObjectPointerType()))) {
if (convertPointersToCompositeType(*this, Loc, LHS, RHS))
@@ -10911,7 +10919,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
// C++ [expr.eq]p4:
// Two operands of type std::nullptr_t or one operand of type
// std::nullptr_t and the other a null pointer constant compare equal.
- if (!IsRelational && LHSIsNull && RHSIsNull) {
+ if (!IsOrdered && LHSIsNull && RHSIsNull) {
if (LHSType->isNullPtrType()) {
RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
return computeResultTy();
@@ -10924,12 +10932,12 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
// Comparison of Objective-C pointers and block pointers against nullptr_t.
// These aren't covered by the composite pointer type rules.
- if (!IsRelational && RHSType->isNullPtrType() &&
+ if (!IsOrdered && RHSType->isNullPtrType() &&
(LHSType->isObjCObjectPointerType() || LHSType->isBlockPointerType())) {
RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
return computeResultTy();
}
- if (!IsRelational && LHSType->isNullPtrType() &&
+ if (!IsOrdered && LHSType->isNullPtrType() &&
(RHSType->isObjCObjectPointerType() || RHSType->isBlockPointerType())) {
LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
return computeResultTy();
@@ -10963,7 +10971,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
// C++ [expr.eq]p2:
// If at least one operand is a pointer to member, [...] bring them to
// their composite pointer type.
- if (!IsRelational &&
+ if (!IsOrdered &&
(LHSType->isMemberPointerType() || RHSType->isMemberPointerType())) {
if (convertPointersToCompositeType(*this, Loc, LHS, RHS))
return QualType();
@@ -10973,7 +10981,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
}
// Handle block pointer types.
- if (!IsRelational && LHSType->isBlockPointerType() &&
+ if (!IsOrdered && LHSType->isBlockPointerType() &&
RHSType->isBlockPointerType()) {
QualType lpointee = LHSType->castAs<BlockPointerType>()->getPointeeType();
QualType rpointee = RHSType->castAs<BlockPointerType>()->getPointeeType();
@@ -10989,7 +10997,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
}
// Allow block pointers to be compared with null pointer constants.
- if (!IsRelational
+ if (!IsOrdered
&& ((LHSType->isBlockPointerType() && RHSType->isPointerType())
|| (LHSType->isPointerType() && RHSType->isBlockPointerType()))) {
if (!LHSIsNull && !RHSIsNull) {
@@ -11059,12 +11067,12 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
return computeResultTy();
}
- if (!IsRelational && LHSType->isBlockPointerType() &&
+ if (!IsOrdered && LHSType->isBlockPointerType() &&
RHSType->isBlockCompatibleObjCPointerType(Context)) {
LHS = ImpCastExprToType(LHS.get(), RHSType,
CK_BlockPointerToObjCPointerCast);
return computeResultTy();
- } else if (!IsRelational &&
+ } else if (!IsOrdered &&
LHSType->isBlockCompatibleObjCPointerType(Context) &&
RHSType->isBlockPointerType()) {
RHS = ImpCastExprToType(RHS.get(), LHSType,
@@ -11081,7 +11089,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
// since users tend to want to compare addresses.
} else if ((LHSIsNull && LHSType->isIntegerType()) ||
(RHSIsNull && RHSType->isIntegerType())) {
- if (IsRelational) {
+ if (IsOrdered) {
isError = getLangOpts().CPlusPlus;
DiagID =
isError ? diag::err_typecheck_ordered_comparison_of_pointer_and_zero
@@ -11090,7 +11098,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
} else if (getLangOpts().CPlusPlus) {
DiagID = diag::err_typecheck_comparison_of_pointer_integer;
isError = true;
- } else if (IsRelational)
+ } else if (IsOrdered)
DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_integer;
else
DiagID = diag::ext_typecheck_comparison_of_pointer_integer;
@@ -11113,12 +11121,12 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
}
// Handle block pointers.
- if (!IsRelational && RHSIsNull
+ if (!IsOrdered && RHSIsNull
&& LHSType->isBlockPointerType() && RHSType->isIntegerType()) {
RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
return computeResultTy();
}
- if (!IsRelational && LHSIsNull
+ if (!IsOrdered && LHSIsNull
&& LHSType->isIntegerType() && RHSType->isBlockPointerType()) {
LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
return computeResultTy();
@@ -11195,6 +11203,11 @@ QualType Sema::GetSignedVectorType(QualType V) {
QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc,
BinaryOperatorKind Opc) {
+ if (Opc == BO_Cmp) {
+ Diag(Loc, diag::err_three_way_vector_comparison);
+ return QualType();
+ }
+
// Check to make sure we're operating on vectors of the same type and width,
// Allowing one side to be a scalar of element type.
QualType vType = CheckVectorOperands(LHS, RHS, Loc, /*isCompAssign*/false,
OpenPOWER on IntegriCloud