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 | 24d189484b4438e8fb6f772cebc91e3f07eac820 (patch) | |
tree | e83c1291922cb1762b8445b7d3a12b132bae4bab /clang/lib/Sema/SemaOverload.cpp | |
parent | 401b39a736e7c139710f5fc7edcd672026139d6b (diff) | |
download | bcm5719-llvm-24d189484b4438e8fb6f772cebc91e3f07eac820.tar.gz bcm5719-llvm-24d189484b4438e8fb6f772cebc91e3f07eac820.zip |
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.
llvm-svn: 111987
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index fd22ad93a09..65cd1833186 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/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 |