Index: include/clang/Sema/TemplateDeduction.h =================================================================== --- include/clang/Sema/TemplateDeduction.h +++ include/clang/Sema/TemplateDeduction.h @@ -68,8 +68,10 @@ /// \brief Take ownership of the SFINAE diagnostic. void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) { assert(HasSFINAEDiagnostic); - PD.first = SuppressedDiagnostics.front().first; - PD.second.swap(SuppressedDiagnostics.front().second); + unsigned NumberOfDiagnostics = SuppressedDiagnostics.size(); + PartialDiagnosticAt &PDiag = SuppressedDiagnostics[((NumberOfDiagnostics == 2) ? 1 : 0)]; + PD.first = PDiag.first; + PD.second.swap(PDiag.second); SuppressedDiagnostics.clear(); HasSFINAEDiagnostic = false; } @@ -98,8 +100,6 @@ /// \brief Add a new diagnostic to the set of diagnostics void addSuppressedDiagnostic(SourceLocation Loc, PartialDiagnostic PD) { - if (HasSFINAEDiagnostic) - return; SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); } Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -9105,6 +9105,16 @@ return; } + // If the diagnsotics is already for overload candidate substitution + // failure, then just emit the diagnostics as is. + if (PDiag && (PDiag->second.getDiagID() == + diag::note_ovl_candidate_substitution_failure || + PDiag->second.getDiagID() == + diag::note_ovl_candidate_disabled_by_enable_if)) { + S.Diag(PDiag->first, PDiag->second); + return; + } + // Format the SFINAE diagnostic into the argument string. // FIXME: Add a general mechanism to include a PartialDiagnostic *'s // formatted message in another diagnostic. @@ -9116,7 +9126,7 @@ PDiag->second.EmitToString(S.getDiagnostics(), SFINAEArgString); } - S.Diag(Templated->getLocation(), + S.Diag(PDiag->first, diag::note_ovl_candidate_substitution_failure) << TemplateArgString << SFINAEArgString << R; MaybeEmitInheritedConstructorNote(S, Templated);