diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:09 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:09 +0000 | 
| commit | 519fc96c475680de2cc49e7811dbbfadb912cbcc (patch) | |
| tree | 310ca684459b7e9ae13c9a3b9abf308b3a634afe /lib/Sema/SemaOverload.cpp | |
| parent | 2298981669bf3bd63335a4be179bc0f96823a8f4 (diff) | |
Notes
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
| -rw-r--r-- | lib/Sema/SemaOverload.cpp | 653 | 
1 files changed, 490 insertions, 163 deletions
| diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index f632a4d3bd1a..47c1e3cec0ea 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -257,8 +257,18 @@ isPointerConversionToVoidPointer(ASTContext& Context) const {  /// Skip any implicit casts which could be either part of a narrowing conversion  /// or after one in an implicit conversion. -static const Expr *IgnoreNarrowingConversion(const Expr *Converted) { -  while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Converted)) { +static const Expr *IgnoreNarrowingConversion(ASTContext &Ctx, +                                             const Expr *Converted) { +  // We can have cleanups wrapping the converted expression; these need to be +  // preserved so that destructors run if necessary. +  if (auto *EWC = dyn_cast<ExprWithCleanups>(Converted)) { +    Expr *Inner = +        const_cast<Expr *>(IgnoreNarrowingConversion(Ctx, EWC->getSubExpr())); +    return ExprWithCleanups::Create(Ctx, Inner, EWC->cleanupsHaveSideEffects(), +                                    EWC->getObjects()); +  } + +  while (auto *ICE = dyn_cast<ImplicitCastExpr>(Converted)) {      switch (ICE->getCastKind()) {      case CK_NoOp:      case CK_IntegralCast: @@ -332,7 +342,7 @@ NarrowingKind StandardConversionSequence::getNarrowingKind(        if (IgnoreFloatToIntegralConversion)          return NK_Not_Narrowing;        llvm::APSInt IntConstantValue; -      const Expr *Initializer = IgnoreNarrowingConversion(Converted); +      const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted);        assert(Initializer && "Unknown conversion expression");        // If it's value-dependent, we can't tell whether it's narrowing. @@ -370,7 +380,7 @@ NarrowingKind StandardConversionSequence::getNarrowingKind(      if (FromType->isRealFloatingType() && ToType->isRealFloatingType() &&          Ctx.getFloatingTypeOrder(FromType, ToType) == 1) {        // FromType is larger than ToType. -      const Expr *Initializer = IgnoreNarrowingConversion(Converted); +      const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted);        // If it's value-dependent, we can't tell whether it's narrowing.        if (Initializer->isValueDependent()) @@ -416,7 +426,7 @@ NarrowingKind StandardConversionSequence::getNarrowingKind(          (FromSigned && !ToSigned)) {        // Not all values of FromType can be represented in ToType.        llvm::APSInt InitializerValue; -      const Expr *Initializer = IgnoreNarrowingConversion(Converted); +      const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted);        // If it's value-dependent, we can't tell whether it's narrowing.        if (Initializer->isValueDependent()) @@ -838,6 +848,25 @@ llvm::Optional<unsigned> DeductionFailureInfo::getCallArgIndex() {    }  } +bool OverloadCandidateSet::OperatorRewriteInfo::shouldAddReversed( +    OverloadedOperatorKind Op) { +  if (!AllowRewrittenCandidates) +    return false; +  return Op == OO_EqualEqual || Op == OO_Spaceship; +} + +bool OverloadCandidateSet::OperatorRewriteInfo::shouldAddReversed( +    ASTContext &Ctx, const FunctionDecl *FD) { +  if (!shouldAddReversed(FD->getDeclName().getCXXOverloadedOperator())) +    return false; +  // Don't bother adding a reversed candidate that can never be a better +  // match than the non-reversed version. +  return FD->getNumParams() != 2 || +         !Ctx.hasSameUnqualifiedType(FD->getParamDecl(0)->getType(), +                                     FD->getParamDecl(1)->getType()) || +         FD->hasAttr<EnableIfAttr>(); +} +  void OverloadCandidateSet::destroyCandidates() {    for (iterator i = begin(), e = end(); i != e; ++i) {      for (auto &C : i->Conversions) @@ -1463,14 +1492,14 @@ bool Sema::IsFunctionConversion(QualType FromType, QualType ToType,    if (TyClass != CanFrom->getTypeClass()) return false;    if (TyClass != Type::FunctionProto && TyClass != Type::FunctionNoProto) {      if (TyClass == Type::Pointer) { -      CanTo = CanTo.getAs<PointerType>()->getPointeeType(); -      CanFrom = CanFrom.getAs<PointerType>()->getPointeeType(); +      CanTo = CanTo.castAs<PointerType>()->getPointeeType(); +      CanFrom = CanFrom.castAs<PointerType>()->getPointeeType();      } else if (TyClass == Type::BlockPointer) { -      CanTo = CanTo.getAs<BlockPointerType>()->getPointeeType(); -      CanFrom = CanFrom.getAs<BlockPointerType>()->getPointeeType(); +      CanTo = CanTo.castAs<BlockPointerType>()->getPointeeType(); +      CanFrom = CanFrom.castAs<BlockPointerType>()->getPointeeType();      } else if (TyClass == Type::MemberPointer) { -      auto ToMPT = CanTo.getAs<MemberPointerType>(); -      auto FromMPT = CanFrom.getAs<MemberPointerType>(); +      auto ToMPT = CanTo.castAs<MemberPointerType>(); +      auto FromMPT = CanFrom.castAs<MemberPointerType>();        // A function pointer conversion cannot change the class of the function.        if (ToMPT->getClass() != FromMPT->getClass())          return false; @@ -2273,7 +2302,7 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,    // Blocks: Block pointers can be converted to void*.    if (FromType->isBlockPointerType() && ToType->isPointerType() && -      ToType->getAs<PointerType>()->getPointeeType()->isVoidType()) { +      ToType->castAs<PointerType>()->getPointeeType()->isVoidType()) {      ConvertedType = ToType;      return true;    } @@ -3272,7 +3301,7 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,      User.ConversionFunction = Constructor;      User.FoundConversionFunction = Best->FoundDecl;      User.After.setAsIdentityConversion(); -    User.After.setFromType(ThisType->getAs<PointerType>()->getPointeeType()); +    User.After.setFromType(ThisType->castAs<PointerType>()->getPointeeType());      User.After.setAllToTypes(ToType);      return Result;    } @@ -3463,7 +3492,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,        User.ConversionFunction = Constructor;        User.FoundConversionFunction = Best->FoundDecl;        User.After.setAsIdentityConversion(); -      User.After.setFromType(ThisType->getAs<PointerType>()->getPointeeType()); +      User.After.setFromType(ThisType->castAs<PointerType>()->getPointeeType());        User.After.setAllToTypes(ToType);        return Result;      } @@ -3755,6 +3784,34 @@ isBetterReferenceBindingKind(const StandardConversionSequence &SCS1,            !SCS2.IsLvalueReference && SCS2.BindsToFunctionLvalue);  } +enum class FixedEnumPromotion { +  None, +  ToUnderlyingType, +  ToPromotedUnderlyingType +}; + +/// Returns kind of fixed enum promotion the \a SCS uses. +static FixedEnumPromotion +getFixedEnumPromtion(Sema &S, const StandardConversionSequence &SCS) { + +  if (SCS.Second != ICK_Integral_Promotion) +    return FixedEnumPromotion::None; + +  QualType FromType = SCS.getFromType(); +  if (!FromType->isEnumeralType()) +    return FixedEnumPromotion::None; + +  EnumDecl *Enum = FromType->getAs<EnumType>()->getDecl(); +  if (!Enum->isFixed()) +    return FixedEnumPromotion::None; + +  QualType UnderlyingType = Enum->getIntegerType(); +  if (S.Context.hasSameType(SCS.getToType(1), UnderlyingType)) +    return FixedEnumPromotion::ToUnderlyingType; + +  return FixedEnumPromotion::ToPromotedUnderlyingType; +} +  /// CompareStandardConversionSequences - Compare two standard  /// conversion sequences to determine whether one is better than the  /// other or if they are indistinguishable (C++ 13.3.3.2p3). @@ -3796,6 +3853,20 @@ CompareStandardConversionSequences(Sema &S, SourceLocation Loc,               ? ImplicitConversionSequence::Better               : ImplicitConversionSequence::Worse; +  // C++14 [over.ics.rank]p4b2: +  // This is retroactively applied to C++11 by CWG 1601. +  // +  //   A conversion that promotes an enumeration whose underlying type is fixed +  //   to its underlying type is better than one that promotes to the promoted +  //   underlying type, if the two are different. +  FixedEnumPromotion FEP1 = getFixedEnumPromtion(S, SCS1); +  FixedEnumPromotion FEP2 = getFixedEnumPromtion(S, SCS2); +  if (FEP1 != FixedEnumPromotion::None && FEP2 != FixedEnumPromotion::None && +      FEP1 != FEP2) +    return FEP1 == FixedEnumPromotion::ToUnderlyingType +               ? ImplicitConversionSequence::Better +               : ImplicitConversionSequence::Worse; +    // C++ [over.ics.rank]p4b2:    //    //   If class B is derived directly or indirectly from class A, @@ -4105,14 +4176,14 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,        /*FIXME: Remove if Objective-C id conversions get their own rank*/        FromType1->isPointerType() && FromType2->isPointerType() &&        ToType1->isPointerType() && ToType2->isPointerType()) { -    QualType FromPointee1 -      = FromType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType(); -    QualType ToPointee1 -      = ToType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType(); -    QualType FromPointee2 -      = FromType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType(); -    QualType ToPointee2 -      = ToType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType(); +    QualType FromPointee1 = +        FromType1->castAs<PointerType>()->getPointeeType().getUnqualifiedType(); +    QualType ToPointee1 = +        ToType1->castAs<PointerType>()->getPointeeType().getUnqualifiedType(); +    QualType FromPointee2 = +        FromType2->castAs<PointerType>()->getPointeeType().getUnqualifiedType(); +    QualType ToPointee2 = +        ToType2->castAs<PointerType>()->getPointeeType().getUnqualifiedType();      //   -- conversion of C* to B* is better than conversion of C* to A*,      if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) { @@ -4301,7 +4372,8 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,                                     QualType OrigT1, QualType OrigT2,                                     bool &DerivedToBase,                                     bool &ObjCConversion, -                                   bool &ObjCLifetimeConversion) { +                                   bool &ObjCLifetimeConversion, +                                   bool &FunctionConversion) {    assert(!OrigT1->isReferenceType() &&      "T1 must be the pointee type of the reference type");    assert(!OrigT2->isReferenceType() && "T2 cannot be a reference type"); @@ -4331,15 +4403,16 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,             Context.canBindObjCObjectType(UnqualT1, UnqualT2))      ObjCConversion = true;    else if (UnqualT2->isFunctionType() && -           IsFunctionConversion(UnqualT2, UnqualT1, ConvertedT2)) +           IsFunctionConversion(UnqualT2, UnqualT1, ConvertedT2)) {      // C++1z [dcl.init.ref]p4:      //   cv1 T1" is reference-compatible with "cv2 T2" if [...] T2 is "noexcept      //   function" and T1 is "function"      //      // We extend this to also apply to 'noreturn', so allow any function      // conversion between function types. +    FunctionConversion = true;      return Ref_Compatible; -  else +  } else      return Ref_Incompatible;    // At this point, we know that T1 and T2 are reference-related (at @@ -4392,7 +4465,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,                           bool AllowExplicit) {    assert(T2->isRecordType() && "Can only find conversions of record types.");    CXXRecordDecl *T2RecordDecl -    = dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl()); +    = dyn_cast<CXXRecordDecl>(T2->castAs<RecordType>()->getDecl());    OverloadCandidateSet CandidateSet(        DeclLoc, OverloadCandidateSet::CSK_InitByUserDefinedConversion); @@ -4420,6 +4493,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,        bool DerivedToBase = false;        bool ObjCConversion = false;        bool ObjCLifetimeConversion = false; +      bool FunctionConversion = false;        // If we are initializing an rvalue reference, don't permit conversion        // functions that return lvalues. @@ -4432,12 +4506,13 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,        if (!ConvTemplate &&            S.CompareReferenceRelationship( -            DeclLoc, -            Conv->getConversionType().getNonReferenceType() -              .getUnqualifiedType(), -            DeclType.getNonReferenceType().getUnqualifiedType(), -            DerivedToBase, ObjCConversion, ObjCLifetimeConversion) == -          Sema::Ref_Incompatible) +              DeclLoc, +              Conv->getConversionType() +                  .getNonReferenceType() +                  .getUnqualifiedType(), +              DeclType.getNonReferenceType().getUnqualifiedType(), +              DerivedToBase, ObjCConversion, ObjCLifetimeConversion, +              FunctionConversion) == Sema::Ref_Incompatible)          continue;      } else {        // If the conversion function doesn't return a reference type, @@ -4523,7 +4598,7 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,    ImplicitConversionSequence ICS;    ICS.setBad(BadConversionSequence::no_conversion, Init, DeclType); -  QualType T1 = DeclType->getAs<ReferenceType>()->getPointeeType(); +  QualType T1 = DeclType->castAs<ReferenceType>()->getPointeeType();    QualType T2 = Init->getType();    // If the initializer is the address of an overloaded function, try @@ -4541,11 +4616,11 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,    bool DerivedToBase = false;    bool ObjCConversion = false;    bool ObjCLifetimeConversion = false; +  bool FunctionConversion = false;    Expr::Classification InitCategory = Init->Classify(S.Context); -  Sema::ReferenceCompareResult RefRelationship -    = S.CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase, -                                     ObjCConversion, ObjCLifetimeConversion); - +  Sema::ReferenceCompareResult RefRelationship = S.CompareReferenceRelationship( +      DeclLoc, T1, T2, DerivedToBase, ObjCConversion, ObjCLifetimeConversion, +      FunctionConversion);    // C++0x [dcl.init.ref]p5:    //   A reference to type "cv1 T1" is initialized by an expression @@ -4920,13 +4995,11 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,      // Type is an aggregate, argument is an init list. At this point it comes      // down to checking whether the initialization works.      // FIXME: Find out whether this parameter is consumed or not. -    // FIXME: Expose SemaInit's aggregate initialization code so that we don't -    // need to call into the initialization code here; overload resolution -    // should not be doing that.      InitializedEntity Entity =          InitializedEntity::InitializeParameter(S.Context, ToType,                                                 /*Consumed=*/false); -    if (S.CanPerformCopyInitialization(Entity, From)) { +    if (S.CanPerformAggregateInitializationForOverloadResolution(Entity, +                                                                 From)) {        Result.setUserDefined();        Result.UserDefined.Before.setAsIdentityConversion();        // Initializer lists don't have a type. @@ -4949,7 +5022,7 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,      // mention initializer lists in any way. So we go by what list-      // initialization would do and try to extrapolate from that. -    QualType T1 = ToType->getAs<ReferenceType>()->getPointeeType(); +    QualType T1 = ToType->castAs<ReferenceType>()->getPointeeType();      // If the initializer list has a single element that is reference-related      // to the parameter type, we initialize the reference from that. @@ -4972,9 +5045,10 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,        bool dummy1 = false;        bool dummy2 = false;        bool dummy3 = false; +      bool dummy4 = false;        Sema::ReferenceCompareResult RefRelationship =            S.CompareReferenceRelationship(From->getBeginLoc(), T1, T2, dummy1, -                                         dummy2, dummy3); +                                         dummy2, dummy3, dummy4);        if (RefRelationship >= Sema::Ref_Related) {          return TryReferenceInit(S, Init, ToType, /*FIXME*/ From->getBeginLoc(), @@ -5219,7 +5293,7 @@ Sema::PerformObjectArgumentInitialization(Expr *From,                                            CXXMethodDecl *Method) {    QualType FromRecordType, DestType;    QualType ImplicitParamRecordType  = -    Method->getThisType()->getAs<PointerType>()->getPointeeType(); +    Method->getThisType()->castAs<PointerType>()->getPointeeType();    Expr::Classification FromClassification;    if (const PointerType *PT = From->getType()->getAs<PointerType>()) { @@ -5467,6 +5541,14 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,    if (Result.isInvalid())      return Result; +  // C++2a [intro.execution]p5: +  //   A full-expression is [...] a constant-expression [...] +  Result = +      S.ActOnFinishFullExpr(Result.get(), From->getExprLoc(), +                            /*DiscardedValue=*/false, /*IsConstexpr=*/true); +  if (Result.isInvalid()) +    return Result; +    // Check for a narrowing implicit conversion.    APValue PreNarrowingValue;    QualType PreNarrowingType; @@ -5998,7 +6080,8 @@ void Sema::AddOverloadCandidate(      FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef<Expr *> Args,      OverloadCandidateSet &CandidateSet, bool SuppressUserConversions,      bool PartialOverloading, bool AllowExplicit, bool AllowExplicitConversions, -    ADLCallKind IsADLCandidate, ConversionSequenceList EarlyConversions) { +    ADLCallKind IsADLCandidate, ConversionSequenceList EarlyConversions, +    OverloadCandidateParamOrder PO) {    const FunctionProtoType *Proto      = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>());    assert(Proto && "Functions without a prototype cannot be overloaded"); @@ -6017,25 +6100,14 @@ void Sema::AddOverloadCandidate(        AddMethodCandidate(Method, FoundDecl, Method->getParent(), QualType(),                           Expr::Classification::makeSimpleLValue(), Args,                           CandidateSet, SuppressUserConversions, -                         PartialOverloading, EarlyConversions); +                         PartialOverloading, EarlyConversions, PO);        return;      }      // We treat a constructor like a non-member function, since its object      // argument doesn't participate in overload resolution.    } -  if (!CandidateSet.isNewCandidate(Function)) -    return; - -  // C++ [over.match.oper]p3: -  //   if no operand has a class type, only those non-member functions in the -  //   lookup set that have a first parameter of type T1 or "reference to -  //   (possibly cv-qualified) T1", when T1 is an enumeration type, or (if there -  //   is a right operand) a second parameter of type T2 or "reference to -  //   (possibly cv-qualified) T2", when T2 is an enumeration type, are -  //   candidate functions. -  if (CandidateSet.getKind() == OverloadCandidateSet::CSK_Operator && -      !IsAcceptableNonMemberOperatorCandidate(Context, Function, Args)) +  if (!CandidateSet.isNewCandidate(Function, PO))      return;    // C++11 [class.copy]p11: [DR1402] @@ -6050,12 +6122,25 @@ void Sema::AddOverloadCandidate(    EnterExpressionEvaluationContext Unevaluated(        *this, Sema::ExpressionEvaluationContext::Unevaluated); +  // C++ [over.match.oper]p3: +  //   if no operand has a class type, only those non-member functions in the +  //   lookup set that have a first parameter of type T1 or "reference to +  //   (possibly cv-qualified) T1", when T1 is an enumeration type, or (if there +  //   is a right operand) a second parameter of type T2 or "reference to +  //   (possibly cv-qualified) T2", when T2 is an enumeration type, are +  //   candidate functions. +  if (CandidateSet.getKind() == OverloadCandidateSet::CSK_Operator && +      !IsAcceptableNonMemberOperatorCandidate(Context, Function, Args)) +    return; +    // Add this candidate    OverloadCandidate &Candidate =        CandidateSet.addCandidate(Args.size(), EarlyConversions);    Candidate.FoundDecl = FoundDecl;    Candidate.Function = Function;    Candidate.Viable = true; +  Candidate.RewriteKind = +      CandidateSet.getRewriteInfo().getRewriteKind(Function, PO);    Candidate.IsSurrogate = false;    Candidate.IsADLCandidate = IsADLCandidate;    Candidate.IgnoreObjectArgument = false; @@ -6155,7 +6240,9 @@ void Sema::AddOverloadCandidate(    // Determine the implicit conversion sequences for each of the    // arguments.    for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { -    if (Candidate.Conversions[ArgIdx].isInitialized()) { +    unsigned ConvIdx = +        PO == OverloadCandidateParamOrder::Reversed ? 1 - ArgIdx : ArgIdx; +    if (Candidate.Conversions[ConvIdx].isInitialized()) {        // We already formed a conversion sequence for this parameter during        // template argument deduction.      } else if (ArgIdx < NumParams) { @@ -6164,12 +6251,12 @@ void Sema::AddOverloadCandidate(        // (13.3.3.1) that converts that argument to the corresponding        // parameter of F.        QualType ParamType = Proto->getParamType(ArgIdx); -      Candidate.Conversions[ArgIdx] = TryCopyInitialization( +      Candidate.Conversions[ConvIdx] = TryCopyInitialization(            *this, Args[ArgIdx], ParamType, SuppressUserConversions,            /*InOverloadResolution=*/true,            /*AllowObjCWritebackConversion=*/            getLangOpts().ObjCAutoRefCount, AllowExplicitConversions); -      if (Candidate.Conversions[ArgIdx].isBad()) { +      if (Candidate.Conversions[ConvIdx].isBad()) {          Candidate.Viable = false;          Candidate.FailureKind = ovl_fail_bad_conversion;          return; @@ -6178,7 +6265,7 @@ void Sema::AddOverloadCandidate(        // (C++ 13.3.2p2): For the purposes of overload resolution, any        // argument for which there is no corresponding parameter is        // considered to ""match the ellipsis" (C+ 13.3.3.1.3). -      Candidate.Conversions[ArgIdx].setEllipsis(); +      Candidate.Conversions[ConvIdx].setEllipsis();      }    } @@ -6525,9 +6612,10 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,          FunctionArgs = Args.slice(1);        }        if (FunTmpl) { -        AddTemplateOverloadCandidate( -            FunTmpl, F.getPair(), ExplicitTemplateArgs, FunctionArgs, -            CandidateSet, SuppressUserConversions, PartialOverloading); +        AddTemplateOverloadCandidate(FunTmpl, F.getPair(), +                                     ExplicitTemplateArgs, FunctionArgs, +                                     CandidateSet, SuppressUserConversions, +                                     PartialOverloading);        } else {          AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet,                               SuppressUserConversions, PartialOverloading); @@ -6538,12 +6626,12 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,  /// AddMethodCandidate - Adds a named decl (which is some kind of  /// method) as a method candidate to the given overload set. -void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, -                              QualType ObjectType, +void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType,                                Expr::Classification ObjectClassification,                                ArrayRef<Expr *> Args, -                              OverloadCandidateSet& CandidateSet, -                              bool SuppressUserConversions) { +                              OverloadCandidateSet &CandidateSet, +                              bool SuppressUserConversions, +                              OverloadCandidateParamOrder PO) {    NamedDecl *Decl = FoundDecl.getDecl();    CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(Decl->getDeclContext()); @@ -6556,11 +6644,11 @@ void Sema::AddMethodCandidate(DeclAccessPair FoundDecl,      AddMethodTemplateCandidate(TD, FoundDecl, ActingContext,                                 /*ExplicitArgs*/ nullptr, ObjectType,                                 ObjectClassification, Args, CandidateSet, -                               SuppressUserConversions); +                               SuppressUserConversions, false, PO);    } else {      AddMethodCandidate(cast<CXXMethodDecl>(Decl), FoundDecl, ActingContext,                         ObjectType, ObjectClassification, Args, CandidateSet, -                       SuppressUserConversions); +                       SuppressUserConversions, false, None, PO);    }  } @@ -6579,14 +6667,15 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,                           OverloadCandidateSet &CandidateSet,                           bool SuppressUserConversions,                           bool PartialOverloading, -                         ConversionSequenceList EarlyConversions) { +                         ConversionSequenceList EarlyConversions, +                         OverloadCandidateParamOrder PO) {    const FunctionProtoType *Proto      = dyn_cast<FunctionProtoType>(Method->getType()->getAs<FunctionType>());    assert(Proto && "Methods without a prototype cannot be overloaded");    assert(!isa<CXXConstructorDecl>(Method) &&           "Use AddOverloadCandidate for constructors"); -  if (!CandidateSet.isNewCandidate(Method)) +  if (!CandidateSet.isNewCandidate(Method, PO))      return;    // C++11 [class.copy]p23: [DR1402] @@ -6605,6 +6694,8 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,        CandidateSet.addCandidate(Args.size() + 1, EarlyConversions);    Candidate.FoundDecl = FoundDecl;    Candidate.Function = Method; +  Candidate.RewriteKind = +      CandidateSet.getRewriteInfo().getRewriteKind(Method, PO);    Candidate.IsSurrogate = false;    Candidate.IgnoreObjectArgument = false;    Candidate.ExplicitCallArguments = Args.size(); @@ -6640,12 +6731,13 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,      // The implicit object argument is ignored.      Candidate.IgnoreObjectArgument = true;    else { +    unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 1 : 0;      // Determine the implicit conversion sequence for the object      // parameter. -    Candidate.Conversions[0] = TryObjectArgumentInitialization( +    Candidate.Conversions[ConvIdx] = TryObjectArgumentInitialization(          *this, CandidateSet.getLocation(), ObjectType, ObjectClassification,          Method, ActingContext); -    if (Candidate.Conversions[0].isBad()) { +    if (Candidate.Conversions[ConvIdx].isBad()) {        Candidate.Viable = false;        Candidate.FailureKind = ovl_fail_bad_conversion;        return; @@ -6664,7 +6756,9 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,    // Determine the implicit conversion sequences for each of the    // arguments.    for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { -    if (Candidate.Conversions[ArgIdx + 1].isInitialized()) { +    unsigned ConvIdx = +        PO == OverloadCandidateParamOrder::Reversed ? 0 : (ArgIdx + 1); +    if (Candidate.Conversions[ConvIdx].isInitialized()) {        // We already formed a conversion sequence for this parameter during        // template argument deduction.      } else if (ArgIdx < NumParams) { @@ -6673,13 +6767,13 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,        // (13.3.3.1) that converts that argument to the corresponding        // parameter of F.        QualType ParamType = Proto->getParamType(ArgIdx); -      Candidate.Conversions[ArgIdx + 1] +      Candidate.Conversions[ConvIdx]          = TryCopyInitialization(*this, Args[ArgIdx], ParamType,                                  SuppressUserConversions,                                  /*InOverloadResolution=*/true,                                  /*AllowObjCWritebackConversion=*/                                    getLangOpts().ObjCAutoRefCount); -      if (Candidate.Conversions[ArgIdx + 1].isBad()) { +      if (Candidate.Conversions[ConvIdx].isBad()) {          Candidate.Viable = false;          Candidate.FailureKind = ovl_fail_bad_conversion;          return; @@ -6688,7 +6782,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,        // (C++ 13.3.2p2): For the purposes of overload resolution, any        // argument for which there is no corresponding parameter is        // considered to "match the ellipsis" (C+ 13.3.3.1.3). -      Candidate.Conversions[ArgIdx + 1].setEllipsis(); +      Candidate.Conversions[ConvIdx].setEllipsis();      }    } @@ -6709,18 +6803,14 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,  /// Add a C++ member function template as a candidate to the candidate  /// set, using template argument deduction to produce an appropriate member  /// function template specialization. -void -Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, -                                 DeclAccessPair FoundDecl, -                                 CXXRecordDecl *ActingContext, -                                 TemplateArgumentListInfo *ExplicitTemplateArgs, -                                 QualType ObjectType, -                                 Expr::Classification ObjectClassification, -                                 ArrayRef<Expr *> Args, -                                 OverloadCandidateSet& CandidateSet, -                                 bool SuppressUserConversions, -                                 bool PartialOverloading) { -  if (!CandidateSet.isNewCandidate(MethodTmpl)) +void Sema::AddMethodTemplateCandidate( +    FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl, +    CXXRecordDecl *ActingContext, +    TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, +    Expr::Classification ObjectClassification, ArrayRef<Expr *> Args, +    OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, +    bool PartialOverloading, OverloadCandidateParamOrder PO) { +  if (!CandidateSet.isNewCandidate(MethodTmpl, PO))      return;    // C++ [over.match.funcs]p7: @@ -6741,13 +6831,15 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,              return CheckNonDependentConversions(                  MethodTmpl, ParamTypes, Args, CandidateSet, Conversions,                  SuppressUserConversions, ActingContext, ObjectType, -                ObjectClassification); +                ObjectClassification, PO);            })) {      OverloadCandidate &Candidate =          CandidateSet.addCandidate(Conversions.size(), Conversions);      Candidate.FoundDecl = FoundDecl;      Candidate.Function = MethodTmpl->getTemplatedDecl();      Candidate.Viable = false; +    Candidate.RewriteKind = +      CandidateSet.getRewriteInfo().getRewriteKind(Candidate.Function, PO);      Candidate.IsSurrogate = false;      Candidate.IgnoreObjectArgument =          cast<CXXMethodDecl>(Candidate.Function)->isStatic() || @@ -6771,7 +6863,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,    AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl,                       ActingContext, ObjectType, ObjectClassification, Args,                       CandidateSet, SuppressUserConversions, PartialOverloading, -                     Conversions); +                     Conversions, PO);  }  /// Add a C++ function template specialization as a candidate @@ -6781,8 +6873,9 @@ void Sema::AddTemplateOverloadCandidate(      FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,      TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,      OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, -    bool PartialOverloading, bool AllowExplicit, ADLCallKind IsADLCandidate) { -  if (!CandidateSet.isNewCandidate(FunctionTemplate)) +    bool PartialOverloading, bool AllowExplicit, ADLCallKind IsADLCandidate, +    OverloadCandidateParamOrder PO) { +  if (!CandidateSet.isNewCandidate(FunctionTemplate, PO))      return;    // C++ [over.match.funcs]p7: @@ -6800,15 +6893,17 @@ void Sema::AddTemplateOverloadCandidate(    if (TemplateDeductionResult Result = DeduceTemplateArguments(            FunctionTemplate, ExplicitTemplateArgs, Args, Specialization, Info,            PartialOverloading, [&](ArrayRef<QualType> ParamTypes) { -            return CheckNonDependentConversions(FunctionTemplate, ParamTypes, -                                                Args, CandidateSet, Conversions, -                                                SuppressUserConversions); +            return CheckNonDependentConversions( +                FunctionTemplate, ParamTypes, Args, CandidateSet, Conversions, +                SuppressUserConversions, nullptr, QualType(), {}, PO);            })) {      OverloadCandidate &Candidate =          CandidateSet.addCandidate(Conversions.size(), Conversions);      Candidate.FoundDecl = FoundDecl;      Candidate.Function = FunctionTemplate->getTemplatedDecl();      Candidate.Viable = false; +    Candidate.RewriteKind = +      CandidateSet.getRewriteInfo().getRewriteKind(Candidate.Function, PO);      Candidate.IsSurrogate = false;      Candidate.IsADLCandidate = IsADLCandidate;      // Ignore the object argument if there is one, since we don't have an object @@ -6833,7 +6928,7 @@ void Sema::AddTemplateOverloadCandidate(    AddOverloadCandidate(        Specialization, FoundDecl, Args, CandidateSet, SuppressUserConversions,        PartialOverloading, AllowExplicit, -      /*AllowExplicitConversions*/ false, IsADLCandidate, Conversions); +      /*AllowExplicitConversions*/ false, IsADLCandidate, Conversions, PO);  }  /// Check that implicit conversion sequences can be formed for each argument @@ -6844,7 +6939,7 @@ bool Sema::CheckNonDependentConversions(      ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet,      ConversionSequenceList &Conversions, bool SuppressUserConversions,      CXXRecordDecl *ActingContext, QualType ObjectType, -    Expr::Classification ObjectClassification) { +    Expr::Classification ObjectClassification, OverloadCandidateParamOrder PO) {    // FIXME: The cases in which we allow explicit conversions for constructor    // arguments never consider calling a constructor template. It's not clear    // that is correct. @@ -6867,10 +6962,11 @@ bool Sema::CheckNonDependentConversions(    // overload resolution is permitted to sidestep instantiations.    if (HasThisConversion && !cast<CXXMethodDecl>(FD)->isStatic() &&        !ObjectType.isNull()) { -    Conversions[0] = TryObjectArgumentInitialization( +    unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 1 : 0; +    Conversions[ConvIdx] = TryObjectArgumentInitialization(          *this, CandidateSet.getLocation(), ObjectType, ObjectClassification,          Method, ActingContext); -    if (Conversions[0].isBad()) +    if (Conversions[ConvIdx].isBad())        return true;    } @@ -6878,14 +6974,17 @@ bool Sema::CheckNonDependentConversions(         ++I) {      QualType ParamType = ParamTypes[I];      if (!ParamType->isDependentType()) { -      Conversions[ThisConversions + I] +      unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed +                             ? 0 +                             : (ThisConversions + I); +      Conversions[ConvIdx]          = TryCopyInitialization(*this, Args[I], ParamType,                                  SuppressUserConversions,                                  /*InOverloadResolution=*/true,                                  /*AllowObjCWritebackConversion=*/                                    getLangOpts().ObjCAutoRefCount,                                  AllowExplicit); -      if (Conversions[ThisConversions + I].isBad()) +      if (Conversions[ConvIdx].isBad())          return true;      }    } @@ -6998,7 +7097,7 @@ void Sema::AddConversionCandidate(    if (const PointerType *FromPtrType = ImplicitParamType->getAs<PointerType>())      ImplicitParamType = FromPtrType->getPointeeType();    CXXRecordDecl *ConversionContext -    = cast<CXXRecordDecl>(ImplicitParamType->getAs<RecordType>()->getDecl()); +    = cast<CXXRecordDecl>(ImplicitParamType->castAs<RecordType>()->getDecl());    Candidate.Conversions[0] = TryObjectArgumentInitialization(        *this, CandidateSet.getLocation(), From->getType(), @@ -7052,10 +7151,9 @@ void Sema::AddConversionCandidate(    // allocator).    QualType CallResultType = ConversionType.getNonLValueExprType(Context); -  llvm::AlignedCharArray<alignof(CallExpr), sizeof(CallExpr) + sizeof(Stmt *)> -      Buffer; +  alignas(CallExpr) char Buffer[sizeof(CallExpr) + sizeof(Stmt *)];    CallExpr *TheTemporaryCall = CallExpr::CreateTemporary( -      Buffer.buffer, &ConversionFn, CallResultType, VK, From->getBeginLoc()); +      Buffer, &ConversionFn, CallResultType, VK, From->getBeginLoc());    ImplicitConversionSequence ICS =        TryCopyInitialization(*this, TheTemporaryCall, ToType, @@ -7274,6 +7372,48 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,    }  } +/// Add all of the non-member operator function declarations in the given +/// function set to the overload candidate set. +void Sema::AddNonMemberOperatorCandidates( +    const UnresolvedSetImpl &Fns, ArrayRef<Expr *> Args, +    OverloadCandidateSet &CandidateSet, +    TemplateArgumentListInfo *ExplicitTemplateArgs) { +  for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) { +    NamedDecl *D = F.getDecl()->getUnderlyingDecl(); +    ArrayRef<Expr *> FunctionArgs = Args; + +    FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D); +    FunctionDecl *FD = +        FunTmpl ? FunTmpl->getTemplatedDecl() : cast<FunctionDecl>(D); + +    // Don't consider rewritten functions if we're not rewriting. +    if (!CandidateSet.getRewriteInfo().isAcceptableCandidate(FD)) +      continue; + +    assert(!isa<CXXMethodDecl>(FD) && +           "unqualified operator lookup found a member function"); + +    if (FunTmpl) { +      AddTemplateOverloadCandidate(FunTmpl, F.getPair(), ExplicitTemplateArgs, +                                   FunctionArgs, CandidateSet); +      if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) +        AddTemplateOverloadCandidate( +            FunTmpl, F.getPair(), ExplicitTemplateArgs, +            {FunctionArgs[1], FunctionArgs[0]}, CandidateSet, false, false, +            true, ADLCallKind::NotADL, OverloadCandidateParamOrder::Reversed); +    } else { +      if (ExplicitTemplateArgs) +        continue; +      AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet); +      if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) +        AddOverloadCandidate(FD, F.getPair(), +                             {FunctionArgs[1], FunctionArgs[0]}, CandidateSet, +                             false, false, true, false, ADLCallKind::NotADL, +                             None, OverloadCandidateParamOrder::Reversed); +    } +  } +} +  /// Add overload candidates for overloaded operators that are  /// member functions.  /// @@ -7285,8 +7425,8 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,  void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,                                         SourceLocation OpLoc,                                         ArrayRef<Expr *> Args, -                                       OverloadCandidateSet& CandidateSet, -                                       SourceRange OpRange) { +                                       OverloadCandidateSet &CandidateSet, +                                       OverloadCandidateParamOrder PO) {    DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);    // C++ [over.match.oper]p3: @@ -7321,7 +7461,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,           ++Oper)        AddMethodCandidate(Oper.getPair(), Args[0]->getType(),                           Args[0]->Classify(Context), Args.slice(1), -                         CandidateSet, /*SuppressUserConversion=*/false); +                         CandidateSet, /*SuppressUserConversion=*/false, PO);    }  } @@ -7776,7 +7916,7 @@ class BuiltinOperatorOverloadBuilder {    static constexpr int ArithmeticTypesCap = 24;    SmallVector<CanQualType, ArithmeticTypesCap> ArithmeticTypes; -  // Define some indices used to iterate over the arithemetic types in +  // Define some indices used to iterate over the arithmetic types in    // ArithmeticTypes.  The "promoted arithmetic types" are the arithmetic    // types are that preserved by promotion (C++ [over.built]p2).    unsigned FirstIntegralType, @@ -8126,10 +8266,16 @@ public:            if (C->Function->isFunctionTemplateSpecialization())              continue; -          QualType FirstParamType = -            C->Function->getParamDecl(0)->getType().getUnqualifiedType(); -          QualType SecondParamType = -            C->Function->getParamDecl(1)->getType().getUnqualifiedType(); +          // We interpret "same parameter-type-list" as applying to the +          // "synthesized candidate, with the order of the two parameters +          // reversed", not to the original function. +          bool Reversed = C->RewriteKind & CRK_Reversed; +          QualType FirstParamType = C->Function->getParamDecl(Reversed ? 1 : 0) +                                        ->getType() +                                        .getUnqualifiedType(); +          QualType SecondParamType = C->Function->getParamDecl(Reversed ? 0 : 1) +                                         ->getType() +                                         .getUnqualifiedType();            // Skip if either parameter isn't of enumeral type.            if (!FirstParamType->isEnumeralType() || @@ -8759,7 +8905,7 @@ public:                    Enum = CandidateTypes[ArgIdx].enumeration_begin(),                 EnumEnd = CandidateTypes[ArgIdx].enumeration_end();               Enum != EnumEnd; ++Enum) { -          if (!(*Enum)->getAs<EnumType>()->getDecl()->isScoped()) +          if (!(*Enum)->castAs<EnumType>()->getDecl()->isScoped())              continue;            if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum)).second) @@ -9183,6 +9329,7 @@ bool clang::isBetterOverloadCandidate(    //   A viable function F1 is defined to be a better function than another    //   viable function F2 if for all arguments i, ICSi(F1) is not a worse    //   conversion sequence than ICSi(F2), and then... +  bool HasWorseConversion = false;    for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) {      switch (CompareImplicitConversionSequences(S, Loc,                                                 Cand1.Conversions[ArgIdx], @@ -9193,6 +9340,24 @@ bool clang::isBetterOverloadCandidate(        break;      case ImplicitConversionSequence::Worse: +      if (Cand1.Function && Cand1.Function == Cand2.Function && +          (Cand2.RewriteKind & CRK_Reversed) != 0) { +        // Work around large-scale breakage caused by considering reversed +        // forms of operator== in C++20: +        // +        // When comparing a function against its reversed form, if we have a +        // better conversion for one argument and a worse conversion for the +        // other, we prefer the non-reversed form. +        // +        // This prevents a conversion function from being considered ambiguous +        // with its own reversed form in various where it's only incidentally +        // heterogeneous. +        // +        // We diagnose this as an extension from CreateOverloadedBinOp. +        HasWorseConversion = true; +        break; +      } +        // Cand1 can't be better than Cand2.        return false; @@ -9206,6 +9371,8 @@ bool clang::isBetterOverloadCandidate(    //       ICSj(F2), or, if not that,    if (HasBetterConversion)      return true; +  if (HasWorseConversion) +    return false;    //   -- the context is an initialization by user-defined conversion    //      (see 8.5, 13.3.1.5) and the standard conversion sequence @@ -9273,8 +9440,10 @@ bool clang::isBetterOverloadCandidate(        return BetterTemplate == Cand1.Function->getPrimaryTemplate();    } -  // FIXME: Work around a defect in the C++17 inheriting constructor wording. -  // A derived-class constructor beats an (inherited) base class constructor. +  //   -- F1 is a constructor for a class D, F2 is a constructor for a base +  //      class B of D, and for all arguments the corresponding parameters of +  //      F1 and F2 have the same type. +  // FIXME: Implement the "all parameters have the same type" check.    bool Cand1IsInherited =        dyn_cast_or_null<ConstructorUsingShadowDecl>(Cand1.FoundDecl.getDecl());    bool Cand2IsInherited = @@ -9292,6 +9461,16 @@ bool clang::isBetterOverloadCandidate(      // Inherited from sibling base classes: still ambiguous.    } +  //   -- F2 is a rewritten candidate (12.4.1.2) and F1 is not +  //   -- F1 and F2 are rewritten candidates, and F2 is a synthesized candidate +  //      with reversed order of parameters and F1 is not +  // +  // We rank reversed + different operator as worse than just reversed, but +  // that comparison can never happen, because we only consider reversing for +  // the maximally-rewritten operator (== or <=>). +  if (Cand1.RewriteKind != Cand2.RewriteKind) +    return Cand1.RewriteKind < Cand2.RewriteKind; +    // Check C++17 tie-breakers for deduction guides.    {      auto *Guide1 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand1.Function); @@ -9425,13 +9604,15 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,      const FunctionDecl *Caller = dyn_cast<FunctionDecl>(S.CurContext);      bool ContainsSameSideCandidate =          llvm::any_of(Candidates, [&](OverloadCandidate *Cand) { -          return Cand->Function && +          // Check viable function only. +          return Cand->Viable && Cand->Function &&                   S.IdentifyCUDAPreference(Caller, Cand->Function) ==                       Sema::CFP_SameSide;          });      if (ContainsSameSideCandidate) {        auto IsWrongSideCandidate = [&](OverloadCandidate *Cand) { -        return Cand->Function && +        // Check viable function only to avoid unnecessary data copying/moving. +        return Cand->Viable && Cand->Function &&                 S.IdentifyCUDAPreference(Caller, Cand->Function) ==                     Sema::CFP_WrongSide;        }; @@ -9485,6 +9666,7 @@ namespace {  enum OverloadCandidateKind {    oc_function,    oc_method, +  oc_reversed_binary_operator,    oc_constructor,    oc_implicit_default_constructor,    oc_implicit_copy_constructor, @@ -9502,6 +9684,7 @@ enum OverloadCandidateSelect {  static std::pair<OverloadCandidateKind, OverloadCandidateSelect>  ClassifyOverloadCandidate(Sema &S, NamedDecl *Found, FunctionDecl *Fn, +                          OverloadCandidateRewriteKind CRK,                            std::string &Description) {    bool isTemplate = Fn->isTemplateDecl() || Found->isTemplateDecl(); @@ -9518,6 +9701,9 @@ ClassifyOverloadCandidate(Sema &S, NamedDecl *Found, FunctionDecl *Fn,    }();    OverloadCandidateKind Kind = [&]() { +    if (CRK & CRK_Reversed) +      return oc_reversed_binary_operator; +      if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn)) {        if (!Ctor->isImplicit()) {          if (isa<ConstructorUsingShadowDecl>(Found)) @@ -9642,6 +9828,7 @@ bool Sema::checkAddressOfFunctionIsAvailable(const FunctionDecl *Function,  // Notes the location of an overload candidate.  void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn, +                                 OverloadCandidateRewriteKind RewriteKind,                                   QualType DestType, bool TakingAddress) {    if (TakingAddress && !checkAddressOfCandidateIsAvailable(*this, Fn))      return; @@ -9651,7 +9838,7 @@ void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn,    std::string FnDesc;    std::pair<OverloadCandidateKind, OverloadCandidateSelect> KSPair = -      ClassifyOverloadCandidate(*this, Found, Fn, FnDesc); +      ClassifyOverloadCandidate(*this, Found, Fn, RewriteKind, FnDesc);    PartialDiagnostic PD = PDiag(diag::note_ovl_candidate)                           << (unsigned)KSPair.first << (unsigned)KSPair.second                           << Fn << FnDesc; @@ -9675,11 +9862,11 @@ void Sema::NoteAllOverloadCandidates(Expr *OverloadedExpr, QualType DestType,         I != IEnd; ++I) {      if (FunctionTemplateDecl *FunTmpl =                  dyn_cast<FunctionTemplateDecl>((*I)->getUnderlyingDecl()) ) { -      NoteOverloadCandidate(*I, FunTmpl->getTemplatedDecl(), DestType, +      NoteOverloadCandidate(*I, FunTmpl->getTemplatedDecl(), CRK_None, DestType,                              TakingAddress);      } else if (FunctionDecl *Fun                        = dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()) ) { -      NoteOverloadCandidate(*I, Fun, DestType, TakingAddress); +      NoteOverloadCandidate(*I, Fun, CRK_None, DestType, TakingAddress);      }    }  } @@ -9729,7 +9916,8 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,    std::string FnDesc;    std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair = -      ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc); +      ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, Cand->RewriteKind, +                                FnDesc);    Expr *FromExpr = Conv.Bad.FromExpr;    QualType FromTy = Conv.Bad.getFromType(); @@ -10001,7 +10189,7 @@ static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D,    std::string Description;    std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair = -      ClassifyOverloadCandidate(S, Found, Fn, Description); +      ClassifyOverloadCandidate(S, Found, Fn, CRK_None, Description);    if (modeCount == 1 && Fn->getParamDecl(0)->getDeclName())      S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity_one) @@ -10298,7 +10486,8 @@ static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) {    std::string FnDesc;    std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair = -      ClassifyOverloadCandidate(S, Cand->FoundDecl, Callee, FnDesc); +      ClassifyOverloadCandidate(S, Cand->FoundDecl, Callee, Cand->RewriteKind, +                                FnDesc);    S.Diag(Callee->getLocation(), diag::note_ovl_candidate_bad_target)        << (unsigned)FnKindPair.first << (unsigned)ocs_non_template @@ -10416,7 +10605,8 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,      if (Fn->isDeleted()) {        std::string FnDesc;        std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair = -          ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc); +          ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, Cand->RewriteKind, +                                    FnDesc);        S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted)            << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc @@ -10426,7 +10616,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,      }      // We don't really have anything else to say about viable candidates. -    S.NoteOverloadCandidate(Cand->FoundDecl, Fn); +    S.NoteOverloadCandidate(Cand->FoundDecl, Fn, Cand->RewriteKind);      return;    } @@ -10459,7 +10649,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,    case ovl_fail_trivial_conversion:    case ovl_fail_bad_final_conversion:    case ovl_fail_final_conversion_not_exact: -    return S.NoteOverloadCandidate(Cand->FoundDecl, Fn); +    return S.NoteOverloadCandidate(Cand->FoundDecl, Fn, Cand->RewriteKind);    case ovl_fail_bad_conversion: {      unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0); @@ -10470,7 +10660,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,      // FIXME: this currently happens when we're called from SemaInit      // when user-conversion overload fails.  Figure out how to handle      // those conditions and diagnose them well. -    return S.NoteOverloadCandidate(Cand->FoundDecl, Fn); +    return S.NoteOverloadCandidate(Cand->FoundDecl, Fn, Cand->RewriteKind);    }    case ovl_fail_bad_target: @@ -10550,12 +10740,12 @@ static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc,    TypeStr += Cand->BuiltinParamTypes[0].getAsString();    if (Cand->Conversions.size() == 1) {      TypeStr += ")"; -    S.Diag(OpLoc, diag::note_ovl_builtin_unary_candidate) << TypeStr; +    S.Diag(OpLoc, diag::note_ovl_builtin_candidate) << TypeStr;    } else {      TypeStr += ", ";      TypeStr += Cand->BuiltinParamTypes[1].getAsString();      TypeStr += ")"; -    S.Diag(OpLoc, diag::note_ovl_builtin_binary_candidate) << TypeStr; +    S.Diag(OpLoc, diag::note_ovl_builtin_candidate) << TypeStr;    }  } @@ -10746,8 +10936,10 @@ struct CompareOverloadCandidatesForDisplay {  /// CompleteNonViableCandidate - Normally, overload resolution only  /// computes up to the first bad conversion. Produces the FixIt set if  /// possible. -static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, -                                       ArrayRef<Expr *> Args) { +static void +CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, +                           ArrayRef<Expr *> Args, +                           OverloadCandidateSet::CandidateSetKind CSK) {    assert(!Cand->Viable);    // Don't do anything on failures other than bad conversion. @@ -10775,6 +10967,7 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,    bool SuppressUserConversions = false;    unsigned ConvIdx = 0; +  unsigned ArgIdx = 0;    ArrayRef<QualType> ParamTypes;    if (Cand->IsSurrogate) { @@ -10782,16 +10975,19 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,        = Cand->Surrogate->getConversionType().getNonReferenceType();      if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())        ConvType = ConvPtrType->getPointeeType(); -    ParamTypes = ConvType->getAs<FunctionProtoType>()->getParamTypes(); -    // Conversion 0 is 'this', which doesn't have a corresponding argument. +    ParamTypes = ConvType->castAs<FunctionProtoType>()->getParamTypes(); +    // Conversion 0 is 'this', which doesn't have a corresponding parameter.      ConvIdx = 1;    } else if (Cand->Function) {      ParamTypes = -        Cand->Function->getType()->getAs<FunctionProtoType>()->getParamTypes(); +        Cand->Function->getType()->castAs<FunctionProtoType>()->getParamTypes();      if (isa<CXXMethodDecl>(Cand->Function) &&          !isa<CXXConstructorDecl>(Cand->Function)) { -      // Conversion 0 is 'this', which doesn't have a corresponding argument. +      // Conversion 0 is 'this', which doesn't have a corresponding parameter.        ConvIdx = 1; +      if (CSK == OverloadCandidateSet::CSK_Operator) +        // Argument 0 is 'this', which doesn't have a corresponding parameter. +        ArgIdx = 1;      }    } else {      // Builtin operator. @@ -10800,16 +10996,19 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,    }    // Fill in the rest of the conversions. -  for (unsigned ArgIdx = 0; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) { +  bool Reversed = Cand->RewriteKind & CRK_Reversed; +  for (unsigned ParamIdx = Reversed ? ParamTypes.size() - 1 : 0; +       ConvIdx != ConvCount; +       ++ConvIdx, ++ArgIdx, ParamIdx += (Reversed ? -1 : 1)) {      if (Cand->Conversions[ConvIdx].isInitialized()) {        // We've already checked this conversion.      } else if (ArgIdx < ParamTypes.size()) { -      if (ParamTypes[ArgIdx]->isDependentType()) +      if (ParamTypes[ParamIdx]->isDependentType())          Cand->Conversions[ConvIdx].setAsIdentityConversion(              Args[ArgIdx]->getType());        else {          Cand->Conversions[ConvIdx] = -            TryCopyInitialization(S, Args[ArgIdx], ParamTypes[ArgIdx], +            TryCopyInitialization(S, Args[ArgIdx], ParamTypes[ParamIdx],                                    SuppressUserConversions,                                    /*InOverloadResolution=*/true,                                    /*AllowObjCWritebackConversion=*/ @@ -10837,7 +11036,7 @@ SmallVector<OverloadCandidate *, 32> OverloadCandidateSet::CompleteCandidates(      if (Cand->Viable)        Cands.push_back(Cand);      else if (OCD == OCD_AllCandidates) { -      CompleteNonViableCandidate(S, Cand, Args); +      CompleteNonViableCandidate(S, Cand, Args, Kind);        if (Cand->Function || Cand->IsSurrogate)          Cands.push_back(Cand);        // Otherwise, this a non-viable builtin candidate.  We do not, in general, @@ -11394,7 +11593,7 @@ public:          if (FunctionDecl *Fun =                  dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()))            if (!functionHasPassObjectSizeParams(Fun)) -            S.NoteOverloadCandidate(*I, Fun, TargetFunctionType, +            S.NoteOverloadCandidate(*I, Fun, CRK_None, TargetFunctionType,                                      /*TakingAddress=*/true);        FailedCandidates.NoteCandidates(S, OvlExpr->getBeginLoc());      } @@ -12344,7 +12543,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,    OverloadCandidateSet CandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator);    // Add the candidates from the given function set. -  AddFunctionCandidates(Fns, ArgsArray, CandidateSet); +  AddNonMemberOperatorCandidates(Fns, ArgsArray, CandidateSet);    // Add operator candidates that are member functions.    AddMemberOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet); @@ -12489,14 +12688,17 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,  ///  /// \param LHS Left-hand argument.  /// \param RHS Right-hand argument. -ExprResult -Sema::CreateOverloadedBinOp(SourceLocation OpLoc, -                            BinaryOperatorKind Opc, -                            const UnresolvedSetImpl &Fns, -                            Expr *LHS, Expr *RHS, bool PerformADL) { +ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, +                                       BinaryOperatorKind Opc, +                                       const UnresolvedSetImpl &Fns, Expr *LHS, +                                       Expr *RHS, bool PerformADL, +                                       bool AllowRewrittenCandidates) {    Expr *Args[2] = { LHS, RHS };    LHS=RHS=nullptr; // Please use only Args instead of LHS/RHS couple +  if (!getLangOpts().CPlusPlus2a) +    AllowRewrittenCandidates = false; +    OverloadedOperatorKind Op = BinaryOperator::getOverloadedOperator(Opc);    DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); @@ -12554,23 +12756,61 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,      return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);    // Build an empty overload set. -  OverloadCandidateSet CandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator); +  OverloadCandidateSet CandidateSet( +      OpLoc, OverloadCandidateSet::CSK_Operator, +      OverloadCandidateSet::OperatorRewriteInfo(Op, AllowRewrittenCandidates)); -  // Add the candidates from the given function set. -  AddFunctionCandidates(Fns, Args, CandidateSet); +  OverloadedOperatorKind ExtraOp = +      AllowRewrittenCandidates ? getRewrittenOverloadedOperator(Op) : OO_None; + +  // Add the candidates from the given function set. This also adds the +  // rewritten candidates using these functions if necessary. +  AddNonMemberOperatorCandidates(Fns, Args, CandidateSet);    // Add operator candidates that are member functions.    AddMemberOperatorCandidates(Op, OpLoc, Args, CandidateSet); +  if (CandidateSet.getRewriteInfo().shouldAddReversed(Op)) +    AddMemberOperatorCandidates(Op, OpLoc, {Args[1], Args[0]}, CandidateSet, +                                OverloadCandidateParamOrder::Reversed); + +  // In C++20, also add any rewritten member candidates. +  if (ExtraOp) { +    AddMemberOperatorCandidates(ExtraOp, OpLoc, Args, CandidateSet); +    if (CandidateSet.getRewriteInfo().shouldAddReversed(ExtraOp)) +      AddMemberOperatorCandidates(ExtraOp, OpLoc, {Args[1], Args[0]}, +                                  CandidateSet, +                                  OverloadCandidateParamOrder::Reversed); +  }    // Add candidates from ADL. Per [over.match.oper]p2, this lookup is not    // performed for an assignment operator (nor for operator[] nor operator->,    // which don't get here). -  if (Opc != BO_Assign && PerformADL) +  if (Opc != BO_Assign && PerformADL) {      AddArgumentDependentLookupCandidates(OpName, OpLoc, Args,                                           /*ExplicitTemplateArgs*/ nullptr,                                           CandidateSet); +    if (ExtraOp) { +      DeclarationName ExtraOpName = +          Context.DeclarationNames.getCXXOperatorName(ExtraOp); +      AddArgumentDependentLookupCandidates(ExtraOpName, OpLoc, Args, +                                           /*ExplicitTemplateArgs*/ nullptr, +                                           CandidateSet); +    } +  }    // Add builtin operator candidates. +  // +  // FIXME: We don't add any rewritten candidates here. This is strictly +  // incorrect; a builtin candidate could be hidden by a non-viable candidate, +  // resulting in our selecting a rewritten builtin candidate. For example: +  // +  //   enum class E { e }; +  //   bool operator!=(E, E) requires false; +  //   bool k = E::e != E::e; +  // +  // ... should select the rewritten builtin candidate 'operator==(E, E)'. But +  // it seems unreasonable to consider rewritten builtin candidates. A core +  // issue has been filed proposing to removed this requirement.    AddBuiltinOperatorCandidates(Op, OpLoc, Args, CandidateSet);    bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -12582,11 +12822,57 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,        // We found a built-in operator or an overloaded operator.        FunctionDecl *FnDecl = Best->Function; +      bool IsReversed = (Best->RewriteKind & CRK_Reversed); +      if (IsReversed) +        std::swap(Args[0], Args[1]); +        if (FnDecl) {          Expr *Base = nullptr;          // We matched an overloaded operator. Build a call to that          // operator. +        OverloadedOperatorKind ChosenOp = +            FnDecl->getDeclName().getCXXOverloadedOperator(); + +        // C++2a [over.match.oper]p9: +        //   If a rewritten operator== candidate is selected by overload +        //   resolution for an operator@, its return type shall be cv bool +        if (Best->RewriteKind && ChosenOp == OO_EqualEqual && +            !FnDecl->getReturnType()->isBooleanType()) { +          Diag(OpLoc, diag::err_ovl_rewrite_equalequal_not_bool) +              << FnDecl->getReturnType() << BinaryOperator::getOpcodeStr(Opc) +              << Args[0]->getSourceRange() << Args[1]->getSourceRange(); +          Diag(FnDecl->getLocation(), diag::note_declared_at); +          return ExprError(); +        } + +        if (AllowRewrittenCandidates && !IsReversed && +            CandidateSet.getRewriteInfo().shouldAddReversed(ChosenOp)) { +          // We could have reversed this operator, but didn't. Check if the +          // reversed form was a viable candidate, and if so, if it had a +          // better conversion for either parameter. If so, this call is +          // formally ambiguous, and allowing it is an extension. +          for (OverloadCandidate &Cand : CandidateSet) { +            if (Cand.Viable && Cand.Function == FnDecl && +                Cand.RewriteKind & CRK_Reversed) { +              for (unsigned ArgIdx = 0; ArgIdx < 2; ++ArgIdx) { +                if (CompareImplicitConversionSequences( +                        *this, OpLoc, Cand.Conversions[ArgIdx], +                        Best->Conversions[ArgIdx]) == +                    ImplicitConversionSequence::Better) { +                  Diag(OpLoc, diag::ext_ovl_ambiguous_oper_binary_reversed) +                      << BinaryOperator::getOpcodeStr(Opc) +                      << Args[0]->getType() << Args[1]->getType() +                      << Args[0]->getSourceRange() << Args[1]->getSourceRange(); +                  Diag(FnDecl->getLocation(), +                       diag::note_ovl_ambiguous_oper_binary_reversed_candidate); +                } +              } +              break; +            } +          } +        } +          // Convert the arguments.          if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {            // Best->Access is only meaningful for class members. @@ -12640,8 +12926,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,          ResultTy = ResultTy.getNonLValueExprType(Context);          CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( -            Context, Op, FnExpr.get(), Args, ResultTy, VK, OpLoc, FPFeatures, -            Best->IsADLCandidate); +            Context, ChosenOp, FnExpr.get(), Args, ResultTy, VK, OpLoc, +            FPFeatures, Best->IsADLCandidate);          if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall,                                  FnDecl)) @@ -12663,7 +12949,46 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,                    isa<CXXMethodDecl>(FnDecl), OpLoc, TheCall->getSourceRange(),                    VariadicDoesNotApply); -        return MaybeBindToTemporary(TheCall); +        ExprResult R = MaybeBindToTemporary(TheCall); +        if (R.isInvalid()) +          return ExprError(); + +        // For a rewritten candidate, we've already reversed the arguments +        // if needed. Perform the rest of the rewrite now. +        if ((Best->RewriteKind & CRK_DifferentOperator) || +            (Op == OO_Spaceship && IsReversed)) { +          if (Op == OO_ExclaimEqual) { +            assert(ChosenOp == OO_EqualEqual && "unexpected operator name"); +            R = CreateBuiltinUnaryOp(OpLoc, UO_LNot, R.get()); +          } else { +            assert(ChosenOp == OO_Spaceship && "unexpected operator name"); +            llvm::APSInt Zero(Context.getTypeSize(Context.IntTy), false); +            Expr *ZeroLiteral = +                IntegerLiteral::Create(Context, Zero, Context.IntTy, OpLoc); + +            Sema::CodeSynthesisContext Ctx; +            Ctx.Kind = Sema::CodeSynthesisContext::RewritingOperatorAsSpaceship; +            Ctx.Entity = FnDecl; +            pushCodeSynthesisContext(Ctx); + +            R = CreateOverloadedBinOp( +                OpLoc, Opc, Fns, IsReversed ? ZeroLiteral : R.get(), +                IsReversed ? R.get() : ZeroLiteral, PerformADL, +                /*AllowRewrittenCandidates=*/false); + +            popCodeSynthesisContext(); +          } +          if (R.isInvalid()) +            return ExprError(); +        } else { +          assert(ChosenOp == Op && "unexpected operator name"); +        } + +        // Make a note in the AST if we did any rewriting. +        if (Best->RewriteKind != CRK_None) +          R = new (Context) CXXRewrittenBinaryOperator(R.get(), IsReversed); + +        return R;        } else {          // We matched a built-in operator. Convert the arguments, then          // break out so that we will build the appropriate built-in @@ -12753,10 +13078,12 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,          return ExprError();        }        CandidateSet.NoteCandidates( -          PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper) -                                         << BinaryOperator::getOpcodeStr(Opc) -                                         << Args[0]->getSourceRange() -                                         << Args[1]->getSourceRange()), +          PartialDiagnosticAt( +              OpLoc, PDiag(diag::err_ovl_deleted_oper) +                         << getOperatorSpelling(Best->Function->getDeclName() +                                                    .getCXXOverloadedOperator()) +                         << Args[0]->getSourceRange() +                         << Args[1]->getSourceRange()),            *this, OCD_AllCandidates, Args, BinaryOperator::getOpcodeStr(Opc),            OpLoc);        return ExprError(); @@ -13633,8 +13960,8 @@ ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R,    OverloadCandidateSet CandidateSet(UDSuffixLoc,                                      OverloadCandidateSet::CSK_Normal); -  AddFunctionCandidates(R.asUnresolvedSet(), Args, CandidateSet, TemplateArgs, -                        /*SuppressUserConversions=*/true); +  AddNonMemberOperatorCandidates(R.asUnresolvedSet(), Args, CandidateSet, +                                 TemplateArgs);    bool HadMultipleCandidates = (CandidateSet.size() > 1); | 
