forked from OSchip/llvm-project
[Sema] Toggle diags when finding allocators (NFCI)
Summary: Many methods in Sema take a `bool Diagnose` parameter. Examples of such methods include `Sema::FindDeallocationFunction` and `Sema::SpecialMemberIsTrivial`. Calling these methods with `Diagnose = false` allows callers to, for instance, check for the existence of a deallocation function, without that check resulting in error diagnostics being emitted if no matching deallocation function exists. Add a similar `bool Diagnose` to the `Sema::FindAllocationFunctions` method, so that checks for the existence of allocation functions can be made without triggering error diagnostics. This allows `SemaCoroutine.cpp`, in its implementation of the Coroutines TS, to check for the existence of a particular `operator new` overload, but then without error fall back to a default `operator new` if no matching overload exists. Test Plan: `check-clang` Reviewers: rsmith, GorNishanov, eric_niebler Reviewed By: GorNishanov Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D42605 llvm-svn: 325288
This commit is contained in:
parent
2b2d8c5eb2
commit
87412d95e3
|
@ -5151,7 +5151,8 @@ public:
|
|||
bool UseGlobal, QualType AllocType, bool IsArray,
|
||||
bool &PassAlignment, MultiExprArg PlaceArgs,
|
||||
FunctionDecl *&OperatorNew,
|
||||
FunctionDecl *&OperatorDelete);
|
||||
FunctionDecl *&OperatorDelete,
|
||||
bool Diagnose = true);
|
||||
void DeclareGlobalNewDelete();
|
||||
void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
|
||||
ArrayRef<QualType> Params);
|
||||
|
|
|
@ -2151,12 +2151,10 @@ bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
resolveAllocationOverload(Sema &S, LookupResult &R, SourceRange Range,
|
||||
SmallVectorImpl<Expr *> &Args, bool &PassAlignment,
|
||||
FunctionDecl *&Operator,
|
||||
OverloadCandidateSet *AlignedCandidates = nullptr,
|
||||
Expr *AlignArg = nullptr) {
|
||||
static bool resolveAllocationOverload(
|
||||
Sema &S, LookupResult &R, SourceRange Range, SmallVectorImpl<Expr *> &Args,
|
||||
bool &PassAlignment, FunctionDecl *&Operator,
|
||||
OverloadCandidateSet *AlignedCandidates, Expr *AlignArg, bool Diagnose) {
|
||||
OverloadCandidateSet Candidates(R.getNameLoc(),
|
||||
OverloadCandidateSet::CSK_Normal);
|
||||
for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end();
|
||||
|
@ -2202,7 +2200,8 @@ resolveAllocationOverload(Sema &S, LookupResult &R, SourceRange Range,
|
|||
AlignArg = Args[1];
|
||||
Args.erase(Args.begin() + 1);
|
||||
return resolveAllocationOverload(S, R, Range, Args, PassAlignment,
|
||||
Operator, &Candidates, AlignArg);
|
||||
Operator, &Candidates, AlignArg,
|
||||
Diagnose);
|
||||
}
|
||||
|
||||
// MSVC will fall back on trying to find a matching global operator new
|
||||
|
@ -2218,48 +2217,53 @@ resolveAllocationOverload(Sema &S, LookupResult &R, SourceRange Range,
|
|||
S.LookupQualifiedName(R, S.Context.getTranslationUnitDecl());
|
||||
// FIXME: This will give bad diagnostics pointing at the wrong functions.
|
||||
return resolveAllocationOverload(S, R, Range, Args, PassAlignment,
|
||||
Operator, nullptr);
|
||||
Operator, /*Candidates=*/nullptr,
|
||||
/*AlignArg=*/nullptr, Diagnose);
|
||||
}
|
||||
|
||||
S.Diag(R.getNameLoc(), diag::err_ovl_no_viable_function_in_call)
|
||||
<< R.getLookupName() << Range;
|
||||
if (Diagnose) {
|
||||
S.Diag(R.getNameLoc(), diag::err_ovl_no_viable_function_in_call)
|
||||
<< R.getLookupName() << Range;
|
||||
|
||||
// If we have aligned candidates, only note the align_val_t candidates
|
||||
// from AlignedCandidates and the non-align_val_t candidates from
|
||||
// Candidates.
|
||||
if (AlignedCandidates) {
|
||||
auto IsAligned = [](OverloadCandidate &C) {
|
||||
return C.Function->getNumParams() > 1 &&
|
||||
C.Function->getParamDecl(1)->getType()->isAlignValT();
|
||||
};
|
||||
auto IsUnaligned = [&](OverloadCandidate &C) { return !IsAligned(C); };
|
||||
// If we have aligned candidates, only note the align_val_t candidates
|
||||
// from AlignedCandidates and the non-align_val_t candidates from
|
||||
// Candidates.
|
||||
if (AlignedCandidates) {
|
||||
auto IsAligned = [](OverloadCandidate &C) {
|
||||
return C.Function->getNumParams() > 1 &&
|
||||
C.Function->getParamDecl(1)->getType()->isAlignValT();
|
||||
};
|
||||
auto IsUnaligned = [&](OverloadCandidate &C) { return !IsAligned(C); };
|
||||
|
||||
// This was an overaligned allocation, so list the aligned candidates
|
||||
// first.
|
||||
Args.insert(Args.begin() + 1, AlignArg);
|
||||
AlignedCandidates->NoteCandidates(S, OCD_AllCandidates, Args, "",
|
||||
R.getNameLoc(), IsAligned);
|
||||
Args.erase(Args.begin() + 1);
|
||||
Candidates.NoteCandidates(S, OCD_AllCandidates, Args, "", R.getNameLoc(),
|
||||
IsUnaligned);
|
||||
} else {
|
||||
Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
|
||||
// This was an overaligned allocation, so list the aligned candidates
|
||||
// first.
|
||||
Args.insert(Args.begin() + 1, AlignArg);
|
||||
AlignedCandidates->NoteCandidates(S, OCD_AllCandidates, Args, "",
|
||||
R.getNameLoc(), IsAligned);
|
||||
Args.erase(Args.begin() + 1);
|
||||
Candidates.NoteCandidates(S, OCD_AllCandidates, Args, "", R.getNameLoc(),
|
||||
IsUnaligned);
|
||||
} else {
|
||||
Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
case OR_Ambiguous:
|
||||
S.Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call)
|
||||
<< R.getLookupName() << Range;
|
||||
Candidates.NoteCandidates(S, OCD_ViableCandidates, Args);
|
||||
if (Diagnose) {
|
||||
S.Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call)
|
||||
<< R.getLookupName() << Range;
|
||||
Candidates.NoteCandidates(S, OCD_ViableCandidates, Args);
|
||||
}
|
||||
return true;
|
||||
|
||||
case OR_Deleted: {
|
||||
S.Diag(R.getNameLoc(), diag::err_ovl_deleted_call)
|
||||
<< Best->Function->isDeleted()
|
||||
<< R.getLookupName()
|
||||
<< S.getDeletedOrUnavailableSuffix(Best->Function)
|
||||
<< Range;
|
||||
Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
|
||||
if (Diagnose) {
|
||||
S.Diag(R.getNameLoc(), diag::err_ovl_deleted_call)
|
||||
<< Best->Function->isDeleted() << R.getLookupName()
|
||||
<< S.getDeletedOrUnavailableSuffix(Best->Function) << Range;
|
||||
Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2274,7 +2278,8 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
|
|||
bool IsArray, bool &PassAlignment,
|
||||
MultiExprArg PlaceArgs,
|
||||
FunctionDecl *&OperatorNew,
|
||||
FunctionDecl *&OperatorDelete) {
|
||||
FunctionDecl *&OperatorDelete,
|
||||
bool Diagnose) {
|
||||
// --- Choosing an allocation function ---
|
||||
// C++ 5.3.4p8 - 14 & 18
|
||||
// 1) If UseGlobal is true, only look in the global scope. Else, also look
|
||||
|
@ -2349,7 +2354,8 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
|
|||
R.suppressDiagnostics();
|
||||
|
||||
if (resolveAllocationOverload(*this, R, Range, AllocArgs, PassAlignment,
|
||||
OperatorNew))
|
||||
OperatorNew, /*Candidates=*/nullptr,
|
||||
/*AlignArg=*/nullptr, Diagnose))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue