[cfe-commits] r89578 - in /cfe/trunk: lib/Parse/ParseExprCXX.cpp lib/Sema/SemaExpr.cpp test/SemaCXX/member-pointers-2.cpp

John McCall rjmccall at apple.com
Sat Nov 21 18:49:44 PST 2009


Author: rjmccall
Date: Sat Nov 21 20:49:43 2009
New Revision: 89578

URL: http://llvm.org/viewvc/llvm-project?rev=89578&view=rev
Log:
If a C++ qualified id is followed by a postfix suffix, it is never the direct
operand of an addressof operator, and so we should not treat it as an abstract
member-pointer expression and therefore suppress the implicit member access.

This is really a well-formedness constraint on expressions:  a DeclRefExpr of
a FieldDecl or a non-static CXXMethodDecl (or template thereof, or unresolved
collection thereof) should not be allowed in an arbitrary location in the AST.
Arguably it shouldn't be allowed anywhere and we should have a different expr
node type for this.  But unfortunately we don't have a good way of enforcing
this kind of constraint right now.


Added:
    cfe/trunk/test/SemaCXX/member-pointers-2.cpp
Modified:
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=89578&r1=89577&r2=89578&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sat Nov 21 20:49:43 2009
@@ -326,6 +326,24 @@
                          /*ObjectType=*/0,
                          Name))
     return ExprError();
+
+  // This is only the direct operand of an & operator if it is not
+  // followed by a postfix-expression suffix.
+  if (isAddressOfOperand) {
+    switch (Tok.getKind()) {
+    case tok::l_square:
+    case tok::l_paren:
+    case tok::arrow:
+    case tok::period:
+    case tok::plusplus:
+    case tok::minusminus:
+      isAddressOfOperand = false;
+      break;
+
+    default:
+      break;
+    }
+  }
   
   return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren),
                                    isAddressOfOperand);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=89578&r1=89577&r2=89578&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Nov 21 20:49:43 2009
@@ -623,6 +623,9 @@
                                                UnqualifiedId &Name,
                                                bool HasTrailingLParen,
                                                bool IsAddressOfOperand) {
+  assert(!(IsAddressOfOperand && HasTrailingLParen) &&
+         "cannot be direct & operand and have a trailing lparen");
+
   if (Name.getKind() == UnqualifiedId::IK_TemplateId) {
     ASTTemplateArgsPtr TemplateArgsPtr(*this,
                                        Name.TemplateId->getTemplateArgs(),
@@ -856,7 +859,7 @@
   // performance.
   if (!ADL) {
     bool isAbstractMemberPointer = 
-      (isAddressOfOperand && !HasTrailingLParen && SS && !SS->isEmpty());
+      (isAddressOfOperand && SS && !SS->isEmpty());
 
     if (!isAbstractMemberPointer && !Lookup.empty() &&
         isa<CXXRecordDecl>((*Lookup.begin())->getDeclContext())) {

Added: cfe/trunk/test/SemaCXX/member-pointers-2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-pointers-2.cpp?rev=89578&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/member-pointers-2.cpp (added)
+++ cfe/trunk/test/SemaCXX/member-pointers-2.cpp Sat Nov 21 20:49:43 2009
@@ -0,0 +1,36 @@
+// RUN: clang-cc -emit-llvm-only %s
+
+// Tests that Sema properly creates member-access expressions for
+// these instead of bare FieldDecls.
+
+struct Foo {
+  int myvalue;
+
+  // We have to override these to get something with an lvalue result.
+  int &operator++(int);
+  int &operator--(int);
+};
+
+struct Test0 {
+  Foo memfoo;
+  int memint;
+  int memarr[10];
+  Test0 *memptr;
+  struct MemClass { int a; } memstruct;
+  int &memfun();
+  
+  void test() {
+    int *p;
+    p = &Test0::memfoo++;
+    p = &Test0::memfoo--;
+    p = &Test0::memarr[1];
+    p = &Test0::memptr->memint;
+    p = &Test0::memstruct.a;
+    p = &Test0::memfun();
+  }
+};
+
+void test0() {
+  Test0 mytest;
+  mytest.test();
+}





More information about the cfe-commits mailing list