diff options
author | John McCall <rjmccall@apple.com> | 2010-08-24 22:52:39 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-24 22:52:39 +0000 |
commit | fb97e75e627599aaa7a613778134e290f9de663b (patch) | |
tree | 18855c1b8c3f75781ed9dd333e7754ae1931766d /lib/Sema/SemaOverload.cpp | |
parent | 4153a060f4cd03e9db1349328a158e9d898a2610 (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.cpp | 34 |
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 |