summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaCast.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaCast.cpp')
-rw-r--r--clang/lib/Sema/SemaCast.cpp58
1 files changed, 45 insertions, 13 deletions
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index ad1d7da4d07..7207d04158a 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -1750,6 +1750,44 @@ static void checkIntToPointerCast(bool CStyle, SourceLocation Loc,
}
}
+static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType,
+ ExprResult &Result) {
+ // We can only fix an overloaded reinterpret_cast if
+ // - it is a template with explicit arguments that resolves to an lvalue
+ // unambiguously, or
+ // - it is the only function in an overload set that may have its address
+ // taken.
+
+ Expr *E = Result.get();
+ // TODO: what if this fails because of DiagnoseUseOfDecl or something
+ // like it?
+ if (Self.ResolveAndFixSingleFunctionTemplateSpecialization(
+ Result,
+ Expr::getValueKindForType(DestType) == VK_RValue // Convert Fun to Ptr
+ ) &&
+ Result.isUsable())
+ return true;
+
+ DeclAccessPair DAP;
+ FunctionDecl *Found = Self.resolveAddressOfOnlyViableOverloadCandidate(E, DAP);
+ if (!Found)
+ 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();
+}
+
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
SourceRange OpRange,
@@ -1761,21 +1799,15 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
QualType SrcType = SrcExpr.get()->getType();
// Is the source an overloaded name? (i.e. &foo)
- // If so, reinterpret_cast can not help us here (13.4, p1, bullet 5) ...
+ // If so, reinterpret_cast generally can not help us here (13.4, p1, bullet 5)
if (SrcType == Self.Context.OverloadTy) {
- // ... unless foo<int> resolves to an lvalue unambiguously.
- // TODO: what if this fails because of DiagnoseUseOfDecl or something
- // like it?
- ExprResult SingleFunctionExpr = SrcExpr;
- if (Self.ResolveAndFixSingleFunctionTemplateSpecialization(
- SingleFunctionExpr,
- Expr::getValueKindForType(DestType) == VK_RValue // Convert Fun to Ptr
- ) && SingleFunctionExpr.isUsable()) {
- SrcExpr = SingleFunctionExpr;
- SrcType = SrcExpr.get()->getType();
- } else {
+ ExprResult FixedExpr = SrcExpr;
+ if (!fixOverloadedReinterpretCastExpr(Self, DestType, FixedExpr))
return TC_NotApplicable;
- }
+
+ assert(FixedExpr.isUsable() && "Invalid result fixing overloaded expr");
+ SrcExpr = FixedExpr;
+ SrcType = SrcExpr.get()->getType();
}
if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {
OpenPOWER on IntegriCloud