aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-08-24 23:26:21 +0000
committerJohn McCall <rjmccall@apple.com>2010-08-24 23:26:21 +0000
commitc988fab9860e83f25ef51101fef162b49380582b (patch)
tree504d9e22e7120b6871b8571585c653f4c88b9421 /lib/Sema/SemaOverload.cpp
parent28a7f258aefdd58db0bbf3a903f053bf2cb69c90 (diff)
Catch the case of trying to turn '&(X::a)' into a member pointer as well.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111997 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp30
1 files changed, 20 insertions, 10 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 65cd183318..6dcb6b01f3 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -6216,9 +6216,24 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
// C++ [over.over]p1:
// [...] The overloaded function name can be preceded by the &
// operator.
- llvm::PointerIntPair<OverloadExpr*,1> Ovl = OverloadExpr::find(From);
- OverloadExpr *OvlExpr = Ovl.getPointer();
-
+ // However, remember whether the expression has member-pointer form:
+ // 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.
+ bool HasFormOfMemberPointer = false;
+ OverloadExpr *OvlExpr;
+ {
+ Expr *Tmp = From->IgnoreParens();
+ if (isa<UnaryOperator>(Tmp)) {
+ Tmp = cast<UnaryOperator>(Tmp)->getSubExpr();
+ OvlExpr = cast<OverloadExpr>(Tmp->IgnoreParens());
+ HasFormOfMemberPointer = (Tmp == OvlExpr && OvlExpr->getQualifier());
+ } else {
+ OvlExpr = cast<OverloadExpr>(Tmp);
+ }
+ }
+
// We expect a pointer or reference to function, or a function pointer.
FunctionType = Context.getCanonicalType(FunctionType).getUnqualifiedType();
if (!FunctionType->isFunctionType()) {
@@ -6230,13 +6245,8 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
}
// 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())) {
+ // member, don't try to convert it to a pointer-to-member type.
+ if (IsMember && !HasFormOfMemberPointer) {
if (!Complain) return 0;
// TODO: Should we condition this on whether any functions might