diff options
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index ffb29795f5..f2c7de2fae 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1409,6 +1409,7 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, } case OR_No_Viable_Function: + case OR_Deleted: // No conversion here! We're done. return false; @@ -3426,6 +3427,14 @@ Sema::BestViableFunction(OverloadCandidateSet& CandidateSet, } // Best is the best viable function. + if (Best->Function && + (Best->Function->isDeleted() || + Best->Function->getAttr<UnavailableAttr>())) + return OR_Deleted; + + // If Best refers to a function that is either deleted (C++0x) or + // unavailable (Clang extension) report an error. + return OR_Success; } @@ -3441,8 +3450,16 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet, for (; Cand != LastCand; ++Cand) { if (Cand->Viable || !OnlyViable) { if (Cand->Function) { - // Normal function - Diag(Cand->Function->getLocation(), diag::err_ovl_candidate); + if (Cand->Function->isDeleted() || + Cand->Function->getAttr<UnavailableAttr>()) { + // Deleted or "unavailable" function. + Diag(Cand->Function->getLocation(), diag::err_ovl_candidate_deleted) + << Cand->Function->isDeleted(); + } else { + // Normal function + // FIXME: Give a better reason! + Diag(Cand->Function->getLocation(), diag::err_ovl_candidate); + } } else if (Cand->IsSurrogate) { // Desugar the type of the surrogate down to a function type, // retaining as many typedefs as possible while still showing @@ -3644,6 +3661,14 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, << UnqualifiedName << Fn->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); break; + + case OR_Deleted: + Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_deleted_call) + << Best->Function->isDeleted() + << UnqualifiedName + << Fn->getSourceRange(); + PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); + break; } // Overload resolution failed. Destroy all of the subexpressions and @@ -3716,6 +3741,15 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false); // FIXME: Leaking incoming expressions! return true; + + case OR_Deleted: + Diag(MemExpr->getSourceRange().getBegin(), + diag::err_ovl_deleted_member_call) + << Best->Function->isDeleted() + << Ovl->getDeclName() << MemExprE->getSourceRange(); + PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false); + // FIXME: Leaking incoming expressions! + return true; } FixOverloadedFunctionReference(MemExpr, Method); @@ -3831,6 +3865,14 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, << Object->getType() << Object->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); break; + + case OR_Deleted: + Diag(Object->getSourceRange().getBegin(), + diag::err_ovl_deleted_object_call) + << Best->Function->isDeleted() + << Object->getType() << Object->getSourceRange(); + PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); + break; } if (Best == CandidateSet.end()) { @@ -3990,6 +4032,13 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, << "operator->" << BasePtr->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); return true; + + case OR_Deleted: + Diag(OpLoc, diag::err_ovl_deleted_oper) + << Best->Function->isDeleted() + << "operator->" << BasePtr->getSourceRange(); + PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); + return true; } // Convert the object parameter. |