diff options
author | George Burgess IV <george.burgess.iv@gmail.com> | 2016-03-19 21:36:10 +0000 |
---|---|---|
committer | George Burgess IV <george.burgess.iv@gmail.com> | 2016-03-19 21:36:10 +0000 |
commit | 3cde9bf9d5734820c1f17981fd235ed98772124a (patch) | |
tree | 80c9f2a4d458386761b81a6190bb5a1d24865bc1 /clang/lib/Sema/SemaOverload.cpp | |
parent | 43165d913aeb61e32877c0d3e9dafa3d926b8c4d (diff) | |
download | bcm5719-llvm-3cde9bf9d5734820c1f17981fd235ed98772124a.tar.gz bcm5719-llvm-3cde9bf9d5734820c1f17981fd235ed98772124a.zip |
[Sema] Allow casting of some overloaded functions
Some functions can't have their address taken. If we encounter an
overload set where only one of the candidates can have its address
taken, we should automatically select that candidate in cast
expressions.
Differential Revision: http://reviews.llvm.org/D17701
llvm-svn: 263887
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index a28ded474a7..3bb9a26c438 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -10419,7 +10419,7 @@ private: return false; QualType ResultTy; - if (Context.hasSameUnqualifiedType(TargetFunctionType, + if (Context.hasSameUnqualifiedType(TargetFunctionType, FunDecl->getType()) || S.IsNoReturnConversion(FunDecl->getType(), TargetFunctionType, ResultTy) || @@ -10652,6 +10652,42 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, } /// \brief Given an expression that refers to an overloaded function, try to +/// resolve that function to a single function that can have its address taken. +/// This will modify `Pair` iff it returns non-null. +/// +/// This routine can only realistically succeed if all but one candidates in the +/// overload set for SrcExpr cannot have their addresses taken. +FunctionDecl * +Sema::resolveAddressOfOnlyViableOverloadCandidate(Expr *E, + DeclAccessPair &Pair) { + OverloadExpr::FindResult R = OverloadExpr::find(E); + OverloadExpr *Ovl = R.Expression; + FunctionDecl *Result = nullptr; + DeclAccessPair DAP; + // Don't use the AddressOfResolver because we're specifically looking for + // cases where we have one overload candidate that lacks + // enable_if/pass_object_size/... + for (auto I = Ovl->decls_begin(), E = Ovl->decls_end(); I != E; ++I) { + auto *FD = dyn_cast<FunctionDecl>(I->getUnderlyingDecl()); + if (!FD) + return nullptr; + + if (!checkAddressOfFunctionIsAvailable(FD)) + continue; + + // We have more than one result; quit. + if (Result) + return nullptr; + DAP = I.getPair(); + Result = FD; + } + + if (Result) + Pair = DAP; + return Result; +} + +/// \brief Given an expression that refers to an overloaded function, try to /// resolve that overloaded function expression down to a single function. /// /// This routine can only resolve template-ids that refer to a single function |