Skip to content

Commit b96daf0

Browse files
dwblaikieMrSidims
authored andcommitted
SemaOverload: Complete candidates before emitting the error, to ensure diagnostics emitted (or suppressed) during completion don't interfere with the overload notes
Because diagnostics and their notes are not connected at the API level, if the error message for an overload is emitted, then the overload candidates are completed - if a diagnostic is emitted during that work, the notes related to overload candidates would be attached to the latter diagnostic, not the original error. Sort of worse, if the latter diagnostic was disabled, the notes are disabled. Reviewers: rsmith Differential Revision: https://reviews.llvm.org/D61357 llvm-svn: 359854
1 parent 5b8e6a0 commit b96daf0

File tree

10 files changed

+338
-179
lines changed

10 files changed

+338
-179
lines changed

clang/include/clang/AST/TemplateName.h

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class NamedDecl;
3131
class NestedNameSpecifier;
3232
enum OverloadedOperatorKind : int;
3333
class OverloadedTemplateStorage;
34+
class PartialDiagnostic;
3435
struct PrintingPolicy;
3536
class QualifiedTemplateName;
3637
class SubstTemplateTemplateParmPackStorage;
@@ -319,6 +320,8 @@ class TemplateName {
319320
/// into a diagnostic with <<.
320321
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
321322
TemplateName N);
323+
const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
324+
TemplateName N);
322325

323326
/// A structure for storing the information associated with a
324327
/// substituted template template parameter.

clang/include/clang/Basic/PartialDiagnostic.h

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H
1717

1818
#include "clang/Basic/Diagnostic.h"
19+
#include "clang/Basic/PartialDiagnostic.h"
1920
#include "clang/Basic/LLVM.h"
2021
#include "clang/Basic/SourceLocation.h"
2122
#include "llvm/ADT/SmallVector.h"

clang/include/clang/Sema/Overload.h

+16-6
Original file line numberDiff line numberDiff line change
@@ -961,13 +961,23 @@ class Sema;
961961
OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc,
962962
OverloadCandidateSet::iterator& Best);
963963

964-
void NoteCandidates(Sema &S,
965-
OverloadCandidateDisplayKind OCD,
966-
ArrayRef<Expr *> Args,
964+
SmallVector<OverloadCandidate *, 32> CompleteCandidates(
965+
Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef<Expr *> Args,
966+
SourceLocation OpLoc = SourceLocation(),
967+
llvm::function_ref<bool(OverloadCandidate &)> Filter =
968+
[](OverloadCandidate &) { return true; });
969+
970+
void NoteCandidates(
971+
PartialDiagnosticAt PA, Sema &S, OverloadCandidateDisplayKind OCD,
972+
ArrayRef<Expr *> Args, StringRef Opc = "",
973+
SourceLocation Loc = SourceLocation(),
974+
llvm::function_ref<bool(OverloadCandidate &)> Filter =
975+
[](OverloadCandidate &) { return true; });
976+
977+
void NoteCandidates(Sema &S, ArrayRef<Expr *> Args,
978+
ArrayRef<OverloadCandidate *> Cands,
967979
StringRef Opc = "",
968-
SourceLocation Loc = SourceLocation(),
969-
llvm::function_ref<bool(OverloadCandidate&)> Filter =
970-
[](OverloadCandidate&) { return true; });
980+
SourceLocation OpLoc = SourceLocation());
971981
};
972982

973983
bool isBetterOverloadCandidate(Sema &S,

clang/lib/AST/TemplateName.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,20 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
250250
return DB << NameStr;
251251
}
252252

253+
const PartialDiagnostic&clang::operator<<(const PartialDiagnostic &PD,
254+
TemplateName N) {
255+
std::string NameStr;
256+
llvm::raw_string_ostream OS(NameStr);
257+
LangOptions LO;
258+
LO.CPlusPlus = true;
259+
LO.Bool = true;
260+
OS << '\'';
261+
N.print(OS, PrintingPolicy(LO));
262+
OS << '\'';
263+
OS.flush();
264+
return PD << NameStr;
265+
}
266+
253267
void TemplateName::dump(raw_ostream &OS) const {
254268
LangOptions LO; // FIXME!
255269
LO.CPlusPlus = true;

clang/lib/Sema/SemaCast.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -399,11 +399,11 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT,
399399
break;
400400
}
401401

402-
S.Diag(range.getBegin(), msg)
403-
<< CT << srcType << destType
404-
<< range << src->getSourceRange();
405-
406-
candidates.NoteCandidates(S, howManyCandidates, src);
402+
candidates.NoteCandidates(
403+
PartialDiagnosticAt(range.getBegin(),
404+
S.PDiag(msg) << CT << srcType << destType << range
405+
<< src->getSourceRange()),
406+
S, howManyCandidates, src);
407407

408408
return true;
409409
}

clang/lib/Sema/SemaExprCXX.cpp

+29-20
Original file line numberDiff line numberDiff line change
@@ -2301,8 +2301,8 @@ static bool resolveAllocationOverload(
23012301
}
23022302

23032303
if (Diagnose) {
2304-
S.Diag(R.getNameLoc(), diag::err_ovl_no_viable_function_in_call)
2305-
<< R.getLookupName() << Range;
2304+
PartialDiagnosticAt PD(R.getNameLoc(), S.PDiag(diag::err_ovl_no_viable_function_in_call)
2305+
<< R.getLookupName() << Range);
23062306

23072307
// If we have aligned candidates, only note the align_val_t candidates
23082308
// from AlignedCandidates and the non-align_val_t candidates from
@@ -2317,30 +2317,34 @@ static bool resolveAllocationOverload(
23172317
// This was an overaligned allocation, so list the aligned candidates
23182318
// first.
23192319
Args.insert(Args.begin() + 1, AlignArg);
2320-
AlignedCandidates->NoteCandidates(S, OCD_AllCandidates, Args, "",
2320+
AlignedCandidates->NoteCandidates(PD, S, OCD_AllCandidates, Args, "",
23212321
R.getNameLoc(), IsAligned);
23222322
Args.erase(Args.begin() + 1);
2323-
Candidates.NoteCandidates(S, OCD_AllCandidates, Args, "", R.getNameLoc(),
2323+
Candidates.NoteCandidates(PD, S, OCD_AllCandidates, Args, "", R.getNameLoc(),
23242324
IsUnaligned);
23252325
} else {
2326-
Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
2326+
Candidates.NoteCandidates(PD, S, OCD_AllCandidates, Args);
23272327
}
23282328
}
23292329
return true;
23302330

23312331
case OR_Ambiguous:
23322332
if (Diagnose) {
2333-
S.Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call)
2334-
<< R.getLookupName() << Range;
2335-
Candidates.NoteCandidates(S, OCD_ViableCandidates, Args);
2333+
Candidates.NoteCandidates(
2334+
PartialDiagnosticAt(R.getNameLoc(),
2335+
S.PDiag(diag::err_ovl_ambiguous_call)
2336+
<< R.getLookupName() << Range),
2337+
S, OCD_ViableCandidates, Args);
23362338
}
23372339
return true;
23382340

23392341
case OR_Deleted: {
23402342
if (Diagnose) {
2341-
S.Diag(R.getNameLoc(), diag::err_ovl_deleted_call)
2342-
<< R.getLookupName() << Range;
2343-
Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
2343+
Candidates.NoteCandidates(
2344+
PartialDiagnosticAt(R.getNameLoc(),
2345+
S.PDiag(diag::err_ovl_deleted_call)
2346+
<< R.getLookupName() << Range),
2347+
S, OCD_AllCandidates, Args);
23442348
}
23452349
return true;
23462350
}
@@ -3504,21 +3508,26 @@ static bool resolveBuiltinNewDeleteOverload(Sema &S, CallExpr *TheCall,
35043508
}
35053509

35063510
case OR_No_Viable_Function:
3507-
S.Diag(R.getNameLoc(), diag::err_ovl_no_viable_function_in_call)
3508-
<< R.getLookupName() << Range;
3509-
Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
3511+
Candidates.NoteCandidates(
3512+
PartialDiagnosticAt(R.getNameLoc(),
3513+
S.PDiag(diag::err_ovl_no_viable_function_in_call)
3514+
<< R.getLookupName() << Range),
3515+
S, OCD_AllCandidates, Args);
35103516
return true;
35113517

35123518
case OR_Ambiguous:
3513-
S.Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call)
3514-
<< R.getLookupName() << Range;
3515-
Candidates.NoteCandidates(S, OCD_ViableCandidates, Args);
3519+
Candidates.NoteCandidates(
3520+
PartialDiagnosticAt(R.getNameLoc(),
3521+
S.PDiag(diag::err_ovl_ambiguous_call)
3522+
<< R.getLookupName() << Range),
3523+
S, OCD_ViableCandidates, Args);
35163524
return true;
35173525

35183526
case OR_Deleted: {
3519-
S.Diag(R.getNameLoc(), diag::err_ovl_deleted_call)
3520-
<< R.getLookupName() << Range;
3521-
Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
3527+
Candidates.NoteCandidates(
3528+
PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_deleted_call)
3529+
<< R.getLookupName() << Range),
3530+
S, OCD_AllCandidates, Args);
35223531
return true;
35233532
}
35243533
}

clang/lib/Sema/SemaInit.cpp

+57-40
Original file line numberDiff line numberDiff line change
@@ -5971,21 +5971,25 @@ static ExprResult CopyObject(Sema &S,
59715971
break;
59725972

59735973
case OR_No_Viable_Function:
5974-
S.Diag(Loc, IsExtraneousCopy && !S.isSFINAEContext()
5975-
? diag::ext_rvalue_to_reference_temp_copy_no_viable
5976-
: diag::err_temp_copy_no_viable)
5977-
<< (int)Entity.getKind() << CurInitExpr->getType()
5978-
<< CurInitExpr->getSourceRange();
5979-
CandidateSet.NoteCandidates(S, OCD_AllCandidates, CurInitExpr);
5974+
CandidateSet.NoteCandidates(
5975+
PartialDiagnosticAt(
5976+
Loc, S.PDiag(IsExtraneousCopy && !S.isSFINAEContext()
5977+
? diag::ext_rvalue_to_reference_temp_copy_no_viable
5978+
: diag::err_temp_copy_no_viable)
5979+
<< (int)Entity.getKind() << CurInitExpr->getType()
5980+
<< CurInitExpr->getSourceRange()),
5981+
S, OCD_AllCandidates, CurInitExpr);
59805982
if (!IsExtraneousCopy || S.isSFINAEContext())
59815983
return ExprError();
59825984
return CurInit;
59835985

59845986
case OR_Ambiguous:
5985-
S.Diag(Loc, diag::err_temp_copy_ambiguous)
5986-
<< (int)Entity.getKind() << CurInitExpr->getType()
5987-
<< CurInitExpr->getSourceRange();
5988-
CandidateSet.NoteCandidates(S, OCD_ViableCandidates, CurInitExpr);
5987+
CandidateSet.NoteCandidates(
5988+
PartialDiagnosticAt(Loc, S.PDiag(diag::err_temp_copy_ambiguous)
5989+
<< (int)Entity.getKind()
5990+
<< CurInitExpr->getType()
5991+
<< CurInitExpr->getSourceRange()),
5992+
S, OCD_ViableCandidates, CurInitExpr);
59895993
return ExprError();
59905994

59915995
case OR_Deleted:
@@ -6120,13 +6124,13 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
61206124
break;
61216125

61226126
case OR_No_Viable_Function:
6123-
S.Diag(Loc, Diag);
6124-
CandidateSet.NoteCandidates(S, OCD_AllCandidates, CurInitExpr);
6127+
CandidateSet.NoteCandidates(PartialDiagnosticAt(Loc, Diag), S,
6128+
OCD_AllCandidates, CurInitExpr);
61256129
break;
61266130

61276131
case OR_Ambiguous:
6128-
S.Diag(Loc, Diag);
6129-
CandidateSet.NoteCandidates(S, OCD_ViableCandidates, CurInitExpr);
6132+
CandidateSet.NoteCandidates(PartialDiagnosticAt(Loc, Diag), S,
6133+
OCD_ViableCandidates, CurInitExpr);
61306134
break;
61316135

61326136
case OR_Deleted:
@@ -8399,19 +8403,22 @@ bool InitializationSequence::Diagnose(Sema &S,
83998403
case FK_UserConversionOverloadFailed:
84008404
switch (FailedOverloadResult) {
84018405
case OR_Ambiguous:
8402-
if (Failure == FK_UserConversionOverloadFailed)
8403-
S.Diag(Kind.getLocation(), diag::err_typecheck_ambiguous_condition)
8404-
<< OnlyArg->getType() << DestType
8405-
<< Args[0]->getSourceRange();
8406-
else
8407-
S.Diag(Kind.getLocation(), diag::err_ref_init_ambiguous)
8408-
<< DestType << OnlyArg->getType()
8409-
<< Args[0]->getSourceRange();
84108406

8411-
FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args);
8407+
FailedCandidateSet.NoteCandidates(
8408+
PartialDiagnosticAt(
8409+
Kind.getLocation(),
8410+
Failure == FK_UserConversionOverloadFailed
8411+
? (S.PDiag(diag::err_typecheck_ambiguous_condition)
8412+
<< OnlyArg->getType() << DestType
8413+
<< Args[0]->getSourceRange())
8414+
: (S.PDiag(diag::err_ref_init_ambiguous)
8415+
<< DestType << OnlyArg->getType()
8416+
<< Args[0]->getSourceRange())),
8417+
S, OCD_ViableCandidates, Args);
84128418
break;
84138419

8414-
case OR_No_Viable_Function:
8420+
case OR_No_Viable_Function: {
8421+
auto Cands = FailedCandidateSet.CompleteCandidates(S, OCD_AllCandidates, Args);
84158422
if (!S.RequireCompleteType(Kind.getLocation(),
84168423
DestType.getNonReferenceType(),
84178424
diag::err_typecheck_nonviable_condition_incomplete,
@@ -8421,9 +8428,9 @@ bool InitializationSequence::Diagnose(Sema &S,
84218428
<< OnlyArg->getType() << Args[0]->getSourceRange()
84228429
<< DestType.getNonReferenceType();
84238430

8424-
FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args);
8431+
FailedCandidateSet.NoteCandidates(S, Args, Cands);
84258432
break;
8426-
8433+
}
84278434
case OR_Deleted: {
84288435
S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function)
84298436
<< OnlyArg->getType() << DestType.getNonReferenceType()
@@ -8587,9 +8594,11 @@ bool InitializationSequence::Diagnose(Sema &S,
85878594
// bad.
85888595
switch (FailedOverloadResult) {
85898596
case OR_Ambiguous:
8590-
S.Diag(Kind.getLocation(), diag::err_ovl_ambiguous_init)
8591-
<< DestType << ArgsRange;
8592-
FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args);
8597+
FailedCandidateSet.NoteCandidates(
8598+
PartialDiagnosticAt(Kind.getLocation(),
8599+
S.PDiag(diag::err_ovl_ambiguous_init)
8600+
<< DestType << ArgsRange),
8601+
S, OCD_ViableCandidates, Args);
85938602
break;
85948603

85958604
case OR_No_Viable_Function:
@@ -8638,9 +8647,12 @@ bool InitializationSequence::Diagnose(Sema &S,
86388647
break;
86398648
}
86408649

8641-
S.Diag(Kind.getLocation(), diag::err_ovl_no_viable_function_in_init)
8642-
<< DestType << ArgsRange;
8643-
FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args);
8650+
FailedCandidateSet.NoteCandidates(
8651+
PartialDiagnosticAt(
8652+
Kind.getLocation(),
8653+
S.PDiag(diag::err_ovl_no_viable_function_in_init)
8654+
<< DestType << ArgsRange),
8655+
S, OCD_AllCandidates, Args);
86448656
break;
86458657

86468658
case OR_Deleted: {
@@ -9438,24 +9450,29 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
94389450

94399451
switch (Result) {
94409452
case OR_Ambiguous:
9441-
Diag(Kind.getLocation(), diag::err_deduced_class_template_ctor_ambiguous)
9442-
<< TemplateName;
94439453
// FIXME: For list-initialization candidates, it'd usually be better to
94449454
// list why they were not viable when given the initializer list itself as
94459455
// an argument.
9446-
Candidates.NoteCandidates(*this, OCD_ViableCandidates, Inits);
9456+
Candidates.NoteCandidates(
9457+
PartialDiagnosticAt(
9458+
Kind.getLocation(),
9459+
PDiag(diag::err_deduced_class_template_ctor_ambiguous)
9460+
<< TemplateName),
9461+
*this, OCD_ViableCandidates, Inits);
94479462
return QualType();
94489463

94499464
case OR_No_Viable_Function: {
94509465
CXXRecordDecl *Primary =
94519466
cast<ClassTemplateDecl>(Template)->getTemplatedDecl();
94529467
bool Complete =
94539468
isCompleteType(Kind.getLocation(), Context.getTypeDeclType(Primary));
9454-
Diag(Kind.getLocation(),
9455-
Complete ? diag::err_deduced_class_template_ctor_no_viable
9456-
: diag::err_deduced_class_template_incomplete)
9457-
<< TemplateName << !Guides.empty();
9458-
Candidates.NoteCandidates(*this, OCD_AllCandidates, Inits);
9469+
Candidates.NoteCandidates(
9470+
PartialDiagnosticAt(
9471+
Kind.getLocation(),
9472+
PDiag(Complete ? diag::err_deduced_class_template_ctor_no_viable
9473+
: diag::err_deduced_class_template_incomplete)
9474+
<< TemplateName << !Guides.empty()),
9475+
*this, OCD_AllCandidates, Inits);
94599476
return QualType();
94609477
}
94619478

0 commit comments

Comments
 (0)