diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ComparisonCategories.cpp | 39 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 104 | ||||
-rw-r--r-- | clang/lib/AST/Interp/Interp.h | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 57 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 25 |
6 files changed, 110 insertions, 130 deletions
diff --git a/clang/lib/AST/ComparisonCategories.cpp b/clang/lib/AST/ComparisonCategories.cpp index 9a07c2494ac..07673230357 100644 --- a/clang/lib/AST/ComparisonCategories.cpp +++ b/clang/lib/AST/ComparisonCategories.cpp @@ -23,31 +23,16 @@ Optional<ComparisonCategoryType> clang::getComparisonCategoryForBuiltinCmp(QualType T) { using CCT = ComparisonCategoryType; - if (const ComplexType *CT = T->getAs<ComplexType>()) { - if (CT->getElementType()->hasFloatingRepresentation()) - return CCT::WeakEquality; - // FIXME: Remove this, consistent with P1959R0. - return CCT::StrongEquality; - } - if (T->isIntegralOrEnumerationType()) return CCT::StrongOrdering; - if (T->hasFloatingRepresentation()) + if (T->isRealFloatingType()) return CCT::PartialOrdering; - // C++2a [expr.spaceship]p7: If the composite pointer type is a function - // pointer type, a pointer-to-member type, or std::nullptr_t, the - // result is of type std::strong_equality - if (T->isFunctionPointerType() || T->isMemberPointerType() || - T->isNullPtrType()) - // FIXME: This case was removed by P1959R0. - return CCT::StrongEquality; - // C++2a [expr.spaceship]p8: If the composite pointer type is an object // pointer type, p <=> q is of type std::strong_ordering. // Note: this assumes neither operand is a null pointer constant. - if (T->isPointerType()) + if (T->isObjectPointerType()) return CCT::StrongOrdering; // TODO: Extend support for operator<=> to ObjC types. @@ -185,10 +170,6 @@ QualType ComparisonCategoryInfo::getType() const { StringRef ComparisonCategories::getCategoryString(ComparisonCategoryType Kind) { using CCKT = ComparisonCategoryType; switch (Kind) { - case CCKT::WeakEquality: - return "weak_equality"; - case CCKT::StrongEquality: - return "strong_equality"; case CCKT::PartialOrdering: return "partial_ordering"; case CCKT::WeakOrdering: @@ -204,12 +185,8 @@ StringRef ComparisonCategories::getResultString(ComparisonCategoryResult Kind) { switch (Kind) { case CCVT::Equal: return "equal"; - case CCVT::Nonequal: - return "nonequal"; case CCVT::Equivalent: return "equivalent"; - case CCVT::Nonequivalent: - return "nonequivalent"; case CCVT::Less: return "less"; case CCVT::Greater: @@ -226,16 +203,10 @@ ComparisonCategories::getPossibleResultsForType(ComparisonCategoryType Type) { using CCR = ComparisonCategoryResult; std::vector<CCR> Values; Values.reserve(4); - bool IsStrong = (Type == CCT::StrongEquality || Type == CCT::StrongOrdering); - if (IsStrong) + bool IsStrong = Type == CCT::StrongOrdering; Values.push_back(IsStrong ? CCR::Equal : CCR::Equivalent); - if (Type == CCT::StrongOrdering || Type == CCT::WeakOrdering || - Type == CCT::PartialOrdering) { - Values.push_back(CCR::Less); - Values.push_back(CCR::Greater); - } else { - Values.push_back(IsStrong ? CCR::Nonequal : CCR::Nonequivalent); - } + Values.push_back(CCR::Less); + Values.push_back(CCR::Greater); if (Type == CCT::PartialOrdering) Values.push_back(CCR::Unordered); return Values; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 9b6d0cb59b0..0b658cbb712 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11481,6 +11481,14 @@ public: } } }; + +enum class CmpResult { + Unequal, + Less, + Equal, + Greater, + Unordered, +}; } template <class SuccessCB, class AfterCB> @@ -11496,15 +11504,8 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, return false; }; - using CCR = ComparisonCategoryResult; - bool IsRelational = E->isRelationalOp(); + bool IsRelational = E->isRelationalOp() || E->getOpcode() == BO_Cmp; bool IsEquality = E->isEqualityOp(); - if (E->getOpcode() == BO_Cmp) { - const ComparisonCategoryInfo &CmpInfo = - Info.Ctx.CompCategories.getInfoForType(E->getType()); - IsRelational = CmpInfo.isOrdered(); - IsEquality = CmpInfo.isEquality(); - } QualType LHSTy = E->getLHS()->getType(); QualType RHSTy = E->getRHS()->getType(); @@ -11518,10 +11519,10 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, if (!EvaluateInteger(E->getRHS(), RHS, Info) || !LHSOK) return false; if (LHS < RHS) - return Success(CCR::Less, E); + return Success(CmpResult::Less, E); if (LHS > RHS) - return Success(CCR::Greater, E); - return Success(CCR::Equal, E); + return Success(CmpResult::Greater, E); + return Success(CmpResult::Equal, E); } if (LHSTy->isFixedPointType() || RHSTy->isFixedPointType()) { @@ -11534,10 +11535,10 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, if (!EvaluateFixedPointOrInteger(E->getRHS(), RHSFX, Info) || !LHSOK) return false; if (LHSFX < RHSFX) - return Success(CCR::Less, E); + return Success(CmpResult::Less, E); if (LHSFX > RHSFX) - return Success(CCR::Greater, E); - return Success(CCR::Equal, E); + return Success(CmpResult::Greater, E); + return Success(CmpResult::Equal, E); } if (LHSTy->isAnyComplexType() || RHSTy->isAnyComplexType()) { @@ -11573,12 +11574,12 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, APFloat::cmpResult CR_i = LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag()); bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual; - return Success(IsEqual ? CCR::Equal : CCR::Nonequal, E); + return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E); } else { assert(IsEquality && "invalid complex comparison"); bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() && LHS.getComplexIntImag() == RHS.getComplexIntImag(); - return Success(IsEqual ? CCR::Equal : CCR::Nonequal, E); + return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E); } } @@ -11597,13 +11598,13 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, auto GetCmpRes = [&]() { switch (LHS.compare(RHS)) { case APFloat::cmpEqual: - return CCR::Equal; + return CmpResult::Equal; case APFloat::cmpLessThan: - return CCR::Less; + return CmpResult::Less; case APFloat::cmpGreaterThan: - return CCR::Greater; + return CmpResult::Greater; case APFloat::cmpUnordered: - return CCR::Unordered; + return CmpResult::Unordered; } llvm_unreachable("Unrecognised APFloat::cmpResult enum"); }; @@ -11658,7 +11659,7 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, if ((RHSValue.Base && isZeroSized(LHSValue)) || (LHSValue.Base && isZeroSized(RHSValue))) return Error(E); - return Success(CCR::Nonequal, E); + return Success(CmpResult::Unequal, E); } const CharUnits &LHSOffset = LHSValue.getLValueOffset(); @@ -11742,10 +11743,10 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, } if (CompareLHS < CompareRHS) - return Success(CCR::Less, E); + return Success(CmpResult::Less, E); if (CompareLHS > CompareRHS) - return Success(CCR::Greater, E); - return Success(CCR::Equal, E); + return Success(CmpResult::Greater, E); + return Success(CmpResult::Equal, E); } if (LHSTy->isMemberPointerType()) { @@ -11766,7 +11767,7 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, // null, they compare unequal. if (!LHSValue.getDecl() || !RHSValue.getDecl()) { bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl(); - return Success(Equal ? CCR::Equal : CCR::Nonequal, E); + return Success(Equal ? CmpResult::Equal : CmpResult::Unequal, E); } // Otherwise if either is a pointer to a virtual member function, the @@ -11783,7 +11784,7 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, // they were dereferenced with a hypothetical object of the associated // class type. bool Equal = LHSValue == RHSValue; - return Success(Equal ? CCR::Equal : CCR::Nonequal, E); + return Success(Equal ? CmpResult::Equal : CmpResult::Unequal, E); } if (LHSTy->isNullPtrType()) { @@ -11792,7 +11793,7 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, // C++11 [expr.rel]p4, [expr.eq]p3: If two operands of type std::nullptr_t // are compared, the result is true of the operator is <=, >= or ==, and // false otherwise. - return Success(CCR::Equal, E); + return Success(CmpResult::Equal, E); } return DoAfter(); @@ -11802,14 +11803,29 @@ bool RecordExprEvaluator::VisitBinCmp(const BinaryOperator *E) { if (!CheckLiteralType(Info, E)) return false; - auto OnSuccess = [&](ComparisonCategoryResult ResKind, - const BinaryOperator *E) { + auto OnSuccess = [&](CmpResult CR, const BinaryOperator *E) { + ComparisonCategoryResult CCR; + switch (CR) { + case CmpResult::Unequal: + llvm_unreachable("should never produce Unequal for three-way comparison"); + case CmpResult::Less: + CCR = ComparisonCategoryResult::Less; + break; + case CmpResult::Equal: + CCR = ComparisonCategoryResult::Equal; + break; + case CmpResult::Greater: + CCR = ComparisonCategoryResult::Greater; + break; + case CmpResult::Unordered: + CCR = ComparisonCategoryResult::Unordered; + break; + } // Evaluation succeeded. Lookup the information for the comparison category // type and fetch the VarDecl for the result. const ComparisonCategoryInfo &CmpInfo = Info.Ctx.CompCategories.getInfoForType(E->getType()); - const VarDecl *VD = - CmpInfo.getValueInfo(CmpInfo.makeWeakResult(ResKind))->VD; + const VarDecl *VD = CmpInfo.getValueInfo(CmpInfo.makeWeakResult(CCR))->VD; // Check and evaluate the result as a constant expression. LValue LV; LV.set(VD); @@ -11837,14 +11853,14 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { "DataRecursiveIntBinOpEvaluator should have handled integral types"); if (E->isComparisonOp()) { - // Evaluate builtin binary comparisons by evaluating them as C++2a three-way + // Evaluate builtin binary comparisons by evaluating them as three-way // comparisons and then translating the result. - auto OnSuccess = [&](ComparisonCategoryResult ResKind, - const BinaryOperator *E) { - using CCR = ComparisonCategoryResult; - bool IsEqual = ResKind == CCR::Equal, - IsLess = ResKind == CCR::Less, - IsGreater = ResKind == CCR::Greater; + auto OnSuccess = [&](CmpResult CR, const BinaryOperator *E) { + assert((CR != CmpResult::Unequal || E->isEqualityOp()) && + "should only produce Unequal for equality comparisons"); + bool IsEqual = CR == CmpResult::Equal, + IsLess = CR == CmpResult::Less, + IsGreater = CR == CmpResult::Greater; auto Op = E->getOpcode(); switch (Op) { default: @@ -11852,10 +11868,14 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { case BO_EQ: case BO_NE: return Success(IsEqual == (Op == BO_EQ), E); - case BO_LT: return Success(IsLess, E); - case BO_GT: return Success(IsGreater, E); - case BO_LE: return Success(IsEqual || IsLess, E); - case BO_GE: return Success(IsEqual || IsGreater, E); + case BO_LT: + return Success(IsLess, E); + case BO_GT: + return Success(IsGreater, E); + case BO_LE: + return Success(IsEqual || IsLess, E); + case BO_GE: + return Success(IsEqual || IsGreater, E); } }; return EvaluateComparisonBinaryOperator(Info, E, OnSuccess, [&]() { diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 8934efa13b9..c12caa639da 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -196,11 +196,8 @@ inline bool CmpHelperEQ<Pointer>(InterpState &S, CodePtr OpPC, CompareFn Fn) { const Pointer &RHS = S.Stk.pop<Pointer>(); const Pointer &LHS = S.Stk.pop<Pointer>(); - if (LHS.isZero() || RHS.isZero()) { - if (LHS.isZero() && RHS.isZero()) - S.Stk.push<BoolT>(BoolT::from(Fn(ComparisonCategoryResult::Equal))); - else - S.Stk.push<BoolT>(BoolT::from(Fn(ComparisonCategoryResult::Nonequal))); + if (LHS.isZero() && RHS.isZero()) { + S.Stk.push<BoolT>(BoolT::from(Fn(ComparisonCategoryResult::Equal))); return true; } diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 9fb399c883c..8de609a2ccd 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -981,10 +981,6 @@ void AggExprEmitter::VisitBinCmp(const BinaryOperator *E) { QualType ArgTy = E->getLHS()->getType(); - // TODO: Handle comparing these types. - if (ArgTy->isVectorType()) - return CGF.ErrorUnsupported( - E, "aggregate three-way comparison with vector arguments"); if (!ArgTy->isIntegralOrEnumerationType() && !ArgTy->isRealFloatingType() && !ArgTy->isNullPtrType() && !ArgTy->isPointerType() && !ArgTy->isMemberPointerType() && !ArgTy->isAnyComplexType()) { @@ -1022,10 +1018,6 @@ void AggExprEmitter::VisitBinCmp(const BinaryOperator *E) { Value *Select; if (ArgTy->isNullPtrType()) { Select = EmitCmpRes(CmpInfo.getEqualOrEquiv()); - } else if (CmpInfo.isEquality()) { - Select = Builder.CreateSelect( - EmitCmp(CK_Equal), EmitCmpRes(CmpInfo.getEqualOrEquiv()), - EmitCmpRes(CmpInfo.getNonequalOrNonequiv()), "sel.eq"); } else if (!CmpInfo.isPartial()) { Value *SelectOne = Builder.CreateSelect(EmitCmp(CK_Less), EmitCmpRes(CmpInfo.getLess()), 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, diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 9c784efed1e..32541d6b944 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -13259,16 +13259,13 @@ ExprResult Sema::BuildSynthesizedThreeWayComparison( if (Eq.isInvalid()) return ExprError(); - ExprResult Less; - if (Info->isOrdered()) { - Less = CreateOverloadedBinOp(OpLoc, BO_LT, Fns, LHS, RHS, true, true, - DefaultedFn); - if (Less.isInvalid()) - return ExprError(); - } + ExprResult Less = CreateOverloadedBinOp(OpLoc, BO_LT, Fns, LHS, RHS, true, + true, DefaultedFn); + if (Less.isInvalid()) + return ExprError(); ExprResult Greater; - if (Info->isOrdered()) { + if (Info->isPartial()) { Greater = CreateOverloadedBinOp(OpLoc, BO_LT, Fns, RHS, LHS, true, true, DefaultedFn); if (Greater.isInvalid()) @@ -13287,17 +13284,7 @@ ExprResult Sema::BuildSynthesizedThreeWayComparison( {ExprResult(), ComparisonCategoryResult::Unordered}, }; - int I; - if (Info->isEquality()) { - Comparisons[1].Result = Info->isStrong() - ? ComparisonCategoryResult::Nonequal - : ComparisonCategoryResult::Nonequivalent; - I = 1; - } else if (!Info->isPartial()) { - I = 2; - } else { - I = 3; - } + int I = Info->isPartial() ? 3 : 2; // Combine the comparisons with suitable conditional expressions. ExprResult Result; |