[cfe-commits] [PATCH] Bound member function fixes
Douglas Gregor
dgregor at apple.com
Mon Dec 20 23:10:10 PST 2010
On Dec 18, 2010, at 6:23 PM, Peter Collingbourne wrote:
> Hi,
>
> This patch series fixes a number of issues associated with bound
> member functions, fixing PR8793 among other things.
>
> OK to commit?
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 863c3c3..d810b46 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3511,6 +3511,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
<< BaseType << int(IsArrow) << BaseExpr->getSourceRange()
<< FixItHint::CreateReplacement(OpLoc, ".");
IsArrow = false;
+ } else if (BaseType->isFunctionType()) {
+ goto fail;
} else {
Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
<< BaseType << BaseExpr->getSourceRange();
I assume that this is for recovery when one writes, e.g.,
x.f->blah
when it should have been
x.f()->blah
Could you add a test case?
--- a/test/SemaCXX/ptrtomember.cpp
+++ b/test/SemaCXX/ptrtomember.cpp
@@ -29,4 +29,6 @@ void f3(S3* p, void (S3::*m)()) {
if (p->*m) {} // expected-error {{a bound member function may only be used to call it}}
p->m; // expected-error {{a bound member function may only be used to call it}}
+
+ void (*mp)() = p ? p->m : p->m; // expected-error {{}}
}
Please add some error text here.
+ if (Ty->isFunctionType()) {
+ // C99 6.3.2.1p4:
+ // "A function designator is an expression that has function type... a
+ // function designator with type ``function returning type'' is converted
+ // to an expression that has type ``pointer to function returning type''."
+ //
+ // C++ 4.3p1:
+ // "An lvalue of function type T can be converted to an rvalue of type
+ // "pointer to T." The result is a pointer to the function."
+ if (!getLangOptions().CPlusPlus || E->isLValue())
+ ImpCastExprToType(E, Context.getPointerType(Ty),
+ CK_FunctionToPointerDecay);
Please use the expression classification code to check for a prvalue here, as specified in the C++0x specification.
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -7804,6 +7804,10 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
Expr *Input) {
UnaryOperatorKind Opc = static_cast<UnaryOperatorKind>(OpcIn);
+ if (Opc != UO_AddrOf && Input->isBoundMemberFunction(Context))
+ return ExprError(Diag(OpLoc, diag::err_invalid_use_of_bound_member_func)
+ << Input->getSourceRange());
+
ExprValueKind VK = VK_RValue;
ExprObjectKind OK = OK_Ordinary;
QualType resultType;
I wonder... would it be better to fold the isBoundMemberFunction() check into CheckPlaceholderExpr, with some flag to CheckPlaceholderExpr that says "this is the address-of, so bound member pointers are okay"? It seems like we'd catch more cases that way.
- Doug
More information about the cfe-commits
mailing list