Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -8977,25 +8977,28 @@ auto Cand1Attrs = Cand1->specific_attrs(); auto Cand2Attrs = Cand2->specific_attrs(); - auto Cand1I = Cand1Attrs.begin(); llvm::FoldingSetNodeID Cand1ID, Cand2ID; - for (EnableIfAttr *Cand2A : Cand2Attrs) { - Cand1ID.clear(); - Cand2ID.clear(); + for (auto Pair : zip_longest(Cand1Attrs, Cand2Attrs)) { + Optional Cand1A = std::get<0>(Pair); + Optional Cand2A = std::get<1>(Pair); // It's impossible for Cand1 to be better than (or equal to) Cand2 if Cand1 - // has fewer enable_if attributes than Cand2. - auto Cand1A = Cand1I++; - if (Cand1A == Cand1Attrs.end()) + // has fewer enable_if attributes than Cand2, and vice versa. + if (!Cand1A) return Comparison::Worse; + if (!Cand2A) + return Comparison::Better; + + Cand1ID.clear(); + Cand2ID.clear(); - Cand1A->getCond()->Profile(Cand1ID, S.getASTContext(), true); - Cand2A->getCond()->Profile(Cand2ID, S.getASTContext(), true); + (*Cand1A)->getCond()->Profile(Cand1ID, S.getASTContext(), true); + (*Cand2A)->getCond()->Profile(Cand2ID, S.getASTContext(), true); if (Cand1ID != Cand2ID) return Comparison::Worse; } - return Cand1I == Cand1Attrs.end() ? Comparison::Equal : Comparison::Better; + return Comparison::Equal; } static bool isBetterMultiversionCandidate(const OverloadCandidate &Cand1, Index: lib/Serialization/ASTReaderDecl.cpp =================================================================== --- lib/Serialization/ASTReaderDecl.cpp +++ lib/Serialization/ASTReaderDecl.cpp @@ -2913,25 +2913,30 @@ // Note that pass_object_size attributes are represented in the function's // ExtParameterInfo, so we don't need to check them here. - // Return false if any of the enable_if expressions of A and B are different. llvm::FoldingSetNodeID Cand1ID, Cand2ID; auto AEnableIfAttrs = A->specific_attrs(); auto BEnableIfAttrs = B->specific_attrs(); - auto AEnableIf = AEnableIfAttrs.begin(); - auto BEnableIf = BEnableIfAttrs.begin(); - for (; AEnableIf != AEnableIfAttrs.end() && BEnableIf != BEnableIfAttrs.end(); - ++BEnableIf, ++AEnableIf) { + + for (auto Pair : zip_longest(AEnableIfAttrs, BEnableIfAttrs)) { + Optional Cand1A = std::get<0>(Pair); + Optional Cand2A = std::get<1>(Pair); + + // Return false if the number of enable_if attributes is different. + if (!Cand1A || !Cand2A) + return false; + Cand1ID.clear(); Cand2ID.clear(); - AEnableIf->getCond()->Profile(Cand1ID, A->getASTContext(), true); - BEnableIf->getCond()->Profile(Cand2ID, B->getASTContext(), true); + (*Cand1A)->getCond()->Profile(Cand1ID, A->getASTContext(), true); + (*Cand2A)->getCond()->Profile(Cand2ID, B->getASTContext(), true); + + // Return false if any of the enable_if expressions of A and B are + // different. if (Cand1ID != Cand2ID) return false; } - - // Return false if the number of enable_if attributes was different. - return AEnableIf == AEnableIfAttrs.end() && BEnableIf == BEnableIfAttrs.end(); + return true; } /// Determine whether the two declarations refer to the same entity.