diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaCast.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 30 |
3 files changed, 47 insertions, 25 deletions
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 7239d44ca23..df32dbdb150 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -1862,24 +1862,12 @@ static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType, Result.isUsable()) return true; - DeclAccessPair DAP; - FunctionDecl *Found = Self.resolveAddressOfOnlyViableOverloadCandidate(E, DAP); - if (!Found) + // No guarantees that ResolveAndFixSingleFunctionTemplateSpecialization + // preserves Result. + Result = E; + if (!Self.resolveAndFixAddressOfOnlyViableOverloadCandidate(Result)) return false; - - // It seems that if we encounter a call to a function that is both unavailable - // and inaccessible, we'll emit multiple diags for said call. Hence, we run - // both checks below unconditionally. - Self.DiagnoseUseOfDecl(Found, E->getExprLoc()); - Self.CheckAddressOfMemberAccess(E, DAP); - - Expr *Fixed = Self.FixOverloadedFunctionReference(E, DAP, Found); - if (Fixed->getType()->isFunctionType()) - Result = Self.DefaultFunctionArrayConversion(Fixed, /*Diagnose=*/false); - else - Result = Fixed; - - return !Result.isInvalid(); + return Result.isUsable(); } static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 29be09e8fea..f4a5dea8f94 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -14911,16 +14911,20 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { case BuiltinType::Overload: { // Try to resolve a single function template specialization. // This is obligatory. - ExprResult result = E; - if (ResolveAndFixSingleFunctionTemplateSpecialization(result, false)) { - return result; + ExprResult Result = E; + if (ResolveAndFixSingleFunctionTemplateSpecialization(Result, false)) + return Result; + + // No guarantees that ResolveAndFixSingleFunctionTemplateSpecialization + // leaves Result unchanged on failure. + Result = E; + if (resolveAndFixAddressOfOnlyViableOverloadCandidate(Result)) + return Result; // If that failed, try to recover with a call. - } else { - tryToRecoverWithCall(result, PDiag(diag::err_ovl_unresolvable), - /*complain*/ true); - return result; - } + tryToRecoverWithCall(Result, PDiag(diag::err_ovl_unresolvable), + /*complain*/ true); + return Result; } // Bound member functions. diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 1c41487f5a4..baf673b5e68 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -10729,6 +10729,36 @@ Sema::resolveAddressOfOnlyViableOverloadCandidate(Expr *E, return Result; } +/// \brief Given an overloaded function, tries to turn it into a non-overloaded +/// function reference using resolveAddressOfOnlyViableOverloadCandidate. This +/// will perform access checks, diagnose the use of the resultant decl, and, if +/// necessary, perform a function-to-pointer decay. +/// +/// Returns false if resolveAddressOfOnlyViableOverloadCandidate fails. +/// Otherwise, returns true. This may emit diagnostics and return true. +bool Sema::resolveAndFixAddressOfOnlyViableOverloadCandidate( + ExprResult &SrcExpr) { + Expr *E = SrcExpr.get(); + assert(E->getType() == Context.OverloadTy && "SrcExpr must be an overload"); + + DeclAccessPair DAP; + FunctionDecl *Found = resolveAddressOfOnlyViableOverloadCandidate(E, DAP); + if (!Found) + return false; + + // Emitting multiple diagnostics for a function that is both inaccessible and + // unavailable is consistent with our behavior elsewhere. So, always check + // for both. + DiagnoseUseOfDecl(Found, E->getExprLoc()); + CheckAddressOfMemberAccess(E, DAP); + Expr *Fixed = FixOverloadedFunctionReference(E, DAP, Found); + if (Fixed->getType()->isFunctionType()) + SrcExpr = DefaultFunctionArrayConversion(Fixed, /*Diagnose=*/false); + else + SrcExpr = Fixed; + return true; +} + /// \brief Given an expression that refers to an overloaded function, try to /// resolve that overloaded function expression down to a single function. /// |