[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