Author: modocache Date: Thu Feb 15 12:09:25 2018 New Revision: 325288 URL: http://llvm.org/viewvc/llvm-project?rev=325288&view=rev Log: [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 Modified: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaExprCXX.cpp Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=325288&r1=325287&r2=325288&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Thu Feb 15 12:09:25 2018 @@ -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); Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=325288&r1=325287&r2=325288&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Feb 15 12:09:25 2018 @@ -2151,12 +2151,10 @@ bool Sema::CheckAllocatedType(QualType A 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, Looku 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, Looku 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 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); + 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); }; + + // 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(Sourc 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(Sourc R.suppressDiagnostics(); if (resolveAllocationOverload(*this, R, Range, AllocArgs, PassAlignment, - OperatorNew)) + OperatorNew, /*Candidates=*/nullptr, + /*AlignArg=*/nullptr, Diagnose)) return true; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits