summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2013-08-01 06:13:59 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2013-08-01 06:13:59 +0000
commita4f7c7a600c3e9db054c8b3b3f075a6a2fb4068f (patch)
treecac3455cb7bdc6814849b18f9b522704edacfd2e /clang/lib/Sema/SemaOverload.cpp
parent0ed37bd525ca412113cf4bb025d302c9076b473e (diff)
downloadbcm5719-llvm-a4f7c7a600c3e9db054c8b3b3f075a6a2fb4068f.tar.gz
bcm5719-llvm-a4f7c7a600c3e9db054c8b3b3f075a6a2fb4068f.zip
Sema: Diagnose explicitly bound unresolved member expressions decaying into pointers to function type
We would disallow the case where the overloaded member expression is coming from an address-of operator but we wouldn't issue any diagnostics when the overloaded member expression comes by way of a function to pointer decay cast. Clang's implementation of DR61 is now seemingly complete. llvm-svn: 187559
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r--clang/lib/Sema/SemaOverload.cpp67
1 files changed, 42 insertions, 25 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 72415518930..1a9b82962ba 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -9282,6 +9282,7 @@ class AddressOfFunctionResolver
bool TargetTypeIsNonStaticMemberFunction;
bool FoundNonTemplateFunction;
+ bool StaticMemberFunctionFromBoundPointer;
OverloadExpr::FindResult OvlExprInfo;
OverloadExpr *OvlExpr;
@@ -9297,33 +9298,35 @@ public:
TargetTypeIsNonStaticMemberFunction(
!!TargetType->getAs<MemberPointerType>()),
FoundNonTemplateFunction(false),
+ StaticMemberFunctionFromBoundPointer(false),
OvlExprInfo(OverloadExpr::find(SourceExpr)),
OvlExpr(OvlExprInfo.Expression),
FailedCandidates(OvlExpr->getNameLoc()) {
ExtractUnqualifiedFunctionTypeFromTargetType();
-
- if (!TargetFunctionType->isFunctionType()) {
- if (OvlExpr->hasExplicitTemplateArgs()) {
- DeclAccessPair dap;
- if (FunctionDecl* Fn = S.ResolveSingleFunctionTemplateSpecialization(
- OvlExpr, false, &dap) ) {
-
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
- if (!Method->isStatic()) {
- // If the target type is a non-function type and the function
- // found is a non-static member function, pretend as if that was
- // the target, it's the only possible type to end up with.
- TargetTypeIsNonStaticMemberFunction = true;
-
- // And skip adding the function if its not in the proper form.
- // We'll diagnose this due to an empty set of functions.
- if (!OvlExprInfo.HasFormOfMemberPointer)
- return;
- }
+
+ if (TargetFunctionType->isFunctionType()) {
+ if (UnresolvedMemberExpr *UME = dyn_cast<UnresolvedMemberExpr>(OvlExpr))
+ if (!UME->isImplicitAccess() &&
+ !S.ResolveSingleFunctionTemplateSpecialization(UME))
+ StaticMemberFunctionFromBoundPointer = true;
+ } else if (OvlExpr->hasExplicitTemplateArgs()) {
+ DeclAccessPair dap;
+ if (FunctionDecl *Fn = S.ResolveSingleFunctionTemplateSpecialization(
+ OvlExpr, false, &dap)) {
+ if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn))
+ if (!Method->isStatic()) {
+ // If the target type is a non-function type and the function found
+ // is a non-static member function, pretend as if that was the
+ // target, it's the only possible type to end up with.
+ TargetTypeIsNonStaticMemberFunction = true;
+
+ // And skip adding the function if its not in the proper form.
+ // We'll diagnose this due to an empty set of functions.
+ if (!OvlExprInfo.HasFormOfMemberPointer)
+ return;
}
- Matches.push_back(std::make_pair(dap,Fn));
- }
+ Matches.push_back(std::make_pair(dap, Fn));
}
return;
}
@@ -9536,7 +9539,7 @@ public:
return TargetTypeIsNonStaticMemberFunction &&
!OvlExprInfo.HasFormOfMemberPointer;
}
-
+
void ComplainIsInvalidFormOfPointerToMemberFunction() const {
// TODO: Should we condition this on whether any functions might
// have matched, or is it more appropriate to do that in callers?
@@ -9544,7 +9547,17 @@ public:
S.Diag(OvlExpr->getNameLoc(), diag::err_addr_ovl_no_qualifier)
<< TargetType << OvlExpr->getSourceRange();
}
-
+
+ bool IsStaticMemberFunctionFromBoundPointer() const {
+ return StaticMemberFunctionFromBoundPointer;
+ }
+
+ void ComplainIsStaticMemberFunctionFromBoundPointer() const {
+ S.Diag(OvlExpr->getLocStart(),
+ diag::err_invalid_form_pointer_member_function)
+ << OvlExpr->getSourceRange();
+ }
+
void ComplainOfInvalidConversion() const {
S.Diag(OvlExpr->getLocStart(), diag::err_addr_ovl_not_func_ptrref)
<< OvlExpr->getName() << TargetType;
@@ -9612,8 +9625,12 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr,
Fn = Resolver.getMatchingFunctionDecl();
assert(Fn);
FoundResult = *Resolver.getMatchingFunctionAccessPair();
- if (Complain)
- CheckAddressOfMemberAccess(AddressOfExpr, FoundResult);
+ if (Complain) {
+ if (Resolver.IsStaticMemberFunctionFromBoundPointer())
+ Resolver.ComplainIsStaticMemberFunctionFromBoundPointer();
+ else
+ CheckAddressOfMemberAccess(AddressOfExpr, FoundResult);
+ }
}
if (pHadMultipleCandidates)
OpenPOWER on IntegriCloud