aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-08-24 22:52:39 +0000
committerJohn McCall <rjmccall@apple.com>2010-08-24 22:52:39 +0000
commitfb97e75e627599aaa7a613778134e290f9de663b (patch)
tree18855c1b8c3f75781ed9dd333e7754ae1931766d /lib/Sema/SemaOverload.cpp
parent4153a060f4cd03e9db1349328a158e9d898a2610 (diff)
When trying to resolve the address of an overloaded expression,
only form pointers-to-member if the expression has the appropriate form. This avoids assertions later on on invalid code, but also allows us to properly resolve mixed-staticity overloads. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111987 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp34
1 files changed, 27 insertions, 7 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index fd22ad93a0..65cd183318 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -6216,13 +6216,9 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
// C++ [over.over]p1:
// [...] The overloaded function name can be preceded by the &
// operator.
- OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
- TemplateArgumentListInfo ETABuffer, *ExplicitTemplateArgs = 0;
- if (OvlExpr->hasExplicitTemplateArgs()) {
- OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer);
- ExplicitTemplateArgs = &ETABuffer;
- }
-
+ llvm::PointerIntPair<OverloadExpr*,1> Ovl = OverloadExpr::find(From);
+ OverloadExpr *OvlExpr = Ovl.getPointer();
+
// We expect a pointer or reference to function, or a function pointer.
FunctionType = Context.getCanonicalType(FunctionType).getUnqualifiedType();
if (!FunctionType->isFunctionType()) {
@@ -6233,6 +6229,30 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
return 0;
}
+ // If the overload expression doesn't have the form of a pointer to
+ // member, don't try to convert it to a pointer-to-member type:
+ // C++ [expr.unary.op]p4:
+ // A pointer to member is only formed when an explicit & is used
+ // and its operand is a qualified-id not enclosed in
+ // parentheses.
+ // We don't diagnose the parentheses here, though. Should we?
+ if (IsMember && !(Ovl.getInt() && OvlExpr->getQualifier())) {
+ if (!Complain) return 0;
+
+ // TODO: Should we condition this on whether any functions might
+ // have matched, or is it more appropriate to do that in callers?
+ // TODO: a fixit wouldn't hurt.
+ Diag(OvlExpr->getNameLoc(), diag::err_addr_ovl_no_qualifier)
+ << ToType << OvlExpr->getSourceRange();
+ return 0;
+ }
+
+ TemplateArgumentListInfo ETABuffer, *ExplicitTemplateArgs = 0;
+ if (OvlExpr->hasExplicitTemplateArgs()) {
+ OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer);
+ ExplicitTemplateArgs = &ETABuffer;
+ }
+
assert(From->getType() == Context.OverloadTy);
// Look through all of the overloaded functions, searching for one