diff options
author | Richard Smith <richard@metafoo.co.uk> | 2019-12-16 17:40:03 -0800 |
---|---|---|
committer | Richard Smith <richard@metafoo.co.uk> | 2019-12-16 17:49:45 -0800 |
commit | f495de43bd5da50286da6020e508d106cfc60f57 (patch) | |
tree | ae8d1dfe2648a19913a6750fd2aeebe54b4d6c1b /clang/lib/Sema/SemaExpr.cpp | |
parent | 4e9f1379b9cd7ddce8cf182707e976ebceb72b05 (diff) | |
download | bcm5719-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.cpp | 57 |
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, |