diff options
author | John McCall <rjmccall@apple.com> | 2010-08-24 23:26:21 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-24 23:26:21 +0000 |
commit | c988fab9860e83f25ef51101fef162b49380582b (patch) | |
tree | 504d9e22e7120b6871b8571585c653f4c88b9421 /lib/Sema/SemaOverload.cpp | |
parent | 28a7f258aefdd58db0bbf3a903f053bf2cb69c90 (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.cpp | 30 |
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 |