]> granicus.if.org Git - clang/commitdiff
Implement [expr.mptr.oper]p6 for '->*' operator.
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 8 Oct 2009 18:00:39 +0000 (18:00 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 8 Oct 2009 18:00:39 +0000 (18:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83562 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/Expr.cpp
test/SemaCXX/builtin-ptrtomember-overload-1.cpp
test/SemaCXX/member-pointer.cpp

index 7461e635c6b5f9804bcf68bcc56a2994253d1a9a..98348d6efc9c7b469df1bc086f87d8ba7ecacb55 100644 (file)
@@ -922,11 +922,21 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
       return BinOp->getRHS()->isLvalue(Ctx);
 
     // C++ [expr.mptr.oper]p6
-    if ((BinOp->getOpcode() == BinaryOperator::PtrMemD ||
-         BinOp->getOpcode() == BinaryOperator::PtrMemI) &&
+    // The result of a .* expression is an lvalue only if its first operand is 
+    // an lvalue and its second operand is a pointer to data member. 
+    if (BinOp->getOpcode() == BinaryOperator::PtrMemD &&
         !BinOp->getType()->isFunctionType())
       return BinOp->getLHS()->isLvalue(Ctx);
 
+    // The result of an ->* expression is an lvalue only if its second operand 
+    // is a pointer to data member.
+    if (BinOp->getOpcode() == BinaryOperator::PtrMemI &&
+        !BinOp->getType()->isFunctionType()) {
+      QualType Ty = BinOp->getRHS()->getType();
+      if (Ty->isMemberPointerType() && !Ty->isMemberFunctionPointerType())
+        return LV_Valid;
+    }
+    
     if (!BinOp->isAssignmentOp())
       return LV_InvalidExpression;
 
index 304e8d139886b85bb99fb3f91341870da162e7b7..46c8ae8b6b93ff6b011b8db8792a3537f7a5a26a 100644 (file)
@@ -36,6 +36,7 @@ struct C1 : B1 {
 
 void foo1(C1 c1, int A::* pmf) {
         int i = c1->*pmf;
+        c1->*pmf = 10;
 }
 
 void foo1(C1 c1, int E::* pmf) {
index 9e407a184c30568c22fe2ca63571725db3017db7..d13b16e6d672723d868be6d714d41733cac89dcb 100644 (file)
@@ -99,7 +99,7 @@ void h() {
   int i = phm->*pi;
   (void)&(hm.*pi);
   (void)&(phm->*pi);
-  (void)&((&hm)->*pi); // expected-error {{address expression must be an lvalue or a function designator}}
+  (void)&((&hm)->*pi); 
 
   void (HasMembers::*pf)() = &HasMembers::f;
   (hm.*pf)();