diff options
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 65e8236952f..d5378b87e0c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -342,6 +342,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, } // See if this is a deleted function. + SmallVector<DiagnoseIfAttr *, 4> DiagnoseIfWarnings; if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { if (FD->isDeleted()) { auto *Ctor = dyn_cast<CXXConstructorDecl>(FD); @@ -363,6 +364,12 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, if (getLangOpts().CUDA && !CheckCUDACall(Loc, FD)) return true; + + if (const DiagnoseIfAttr *A = + checkArgIndependentDiagnoseIf(FD, DiagnoseIfWarnings)) { + emitDiagnoseIfDiagnostic(Loc, A); + return true; + } } // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions @@ -377,6 +384,10 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, Diag(D->getLocation(), diag::note_entity_declared_at) << D; return true; } + + for (const auto *W : DiagnoseIfWarnings) + emitDiagnoseIfDiagnostic(Loc, W); + DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass, ObjCPropertyAccess); @@ -5154,12 +5165,40 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context, return OverloadDecl; } -static bool isNumberOfArgsValidForCall(Sema &S, const FunctionDecl *Callee, - std::size_t NumArgs) { - if (S.TooManyArguments(Callee->getNumParams(), NumArgs, - /*PartialOverloading=*/false)) - return Callee->isVariadic(); - return Callee->getMinRequiredArguments() <= NumArgs; +static void checkDirectCallValidity(Sema &S, const Expr *Fn, + FunctionDecl *Callee, + MultiExprArg ArgExprs) { + // `Callee` (when called with ArgExprs) may be ill-formed. enable_if (and + // similar attributes) really don't like it when functions are called with an + // invalid number of args. + if (S.TooManyArguments(Callee->getNumParams(), ArgExprs.size(), + /*PartialOverloading=*/false) && + !Callee->isVariadic()) + return; + if (Callee->getMinRequiredArguments() > ArgExprs.size()) + return; + + if (const EnableIfAttr *Attr = S.CheckEnableIf(Callee, ArgExprs, true)) { + S.Diag(Fn->getLocStart(), + isa<CXXMethodDecl>(Callee) + ? diag::err_ovl_no_viable_member_function_in_call + : diag::err_ovl_no_viable_function_in_call) + << Callee << Callee->getSourceRange(); + S.Diag(Callee->getLocation(), + diag::note_ovl_candidate_disabled_by_function_cond_attr) + << Attr->getCond()->getSourceRange() << Attr->getMessage(); + return; + } + + SmallVector<DiagnoseIfAttr *, 4> Nonfatal; + if (const DiagnoseIfAttr *Attr = S.checkArgDependentDiagnoseIf( + Callee, ArgExprs, Nonfatal, /*MissingImplicitThis=*/true)) { + S.emitDiagnoseIfDiagnostic(Fn->getLocStart(), Attr); + return; + } + + for (const auto *W : Nonfatal) + S.emitDiagnoseIfDiagnostic(Fn->getLocStart(), W); } /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. @@ -5294,26 +5333,8 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, if (getLangOpts().OpenCL && checkOpenCLDisabledDecl(*FD, *Fn)) return ExprError(); - - // CheckEnableIf assumes that the we're passing in a sane number of args for - // FD, but that doesn't always hold true here. This is because, in some - // cases, we'll emit a diag about an ill-formed function call, but then - // we'll continue on as if the function call wasn't ill-formed. So, if the - // number of args looks incorrect, don't do enable_if checks; we should've - // already emitted an error about the bad call. - if (FD->hasAttr<EnableIfAttr>() && - isNumberOfArgsValidForCall(*this, FD, ArgExprs.size())) { - if (const EnableIfAttr *Attr = CheckEnableIf(FD, ArgExprs, true)) { - Diag(Fn->getLocStart(), - isa<CXXMethodDecl>(FD) - ? diag::err_ovl_no_viable_member_function_in_call - : diag::err_ovl_no_viable_function_in_call) - << FD << FD->getSourceRange(); - Diag(FD->getLocation(), - diag::note_ovl_candidate_disabled_by_enable_if_attr) - << Attr->getCond()->getSourceRange() << Attr->getMessage(); - } - } + + checkDirectCallValidity(*this, Fn, FD, ArgExprs); } return BuildResolvedCallExpr(Fn, NDecl, LParenLoc, ArgExprs, RParenLoc, |