[cfe-commits] r95638 - in /cfe/trunk: lib/AST/CXXInheritance.cpp test/CXX/conv/conv.mem/p4.cpp

John McCall rjmccall at apple.com
Mon Feb 8 16:57:12 PST 2010


Author: rjmccall
Date: Mon Feb  8 18:57:12 2010
New Revision: 95638

URL: http://llvm.org/viewvc/llvm-project?rev=95638&view=rev
Log:
Reset the found-virtual-base state unless the *current* base produces a path,
not *any* base up to now has produced a path.  Fixes PR 6254.

I'll do the access-control part of this patch RSN.


Added:
    cfe/trunk/test/CXX/conv/conv.mem/p4.cpp
Modified:
    cfe/trunk/lib/AST/CXXInheritance.cpp

Modified: cfe/trunk/lib/AST/CXXInheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CXXInheritance.cpp?rev=95638&r1=95637&r2=95638&view=diff

==============================================================================
--- cfe/trunk/lib/AST/CXXInheritance.cpp (original)
+++ cfe/trunk/lib/AST/CXXInheritance.cpp Mon Feb  8 18:57:12 2010
@@ -215,10 +215,13 @@
         Paths.ScratchPath.Access
           = MergeAccess(AccessToHere, BaseSpec->getAccessSpecifier());
     }
-        
+    
+    // Track whether there's a path involving this specific base.
+    bool FoundPathThroughBase = false;
+    
     if (BaseMatches(BaseSpec, Paths.ScratchPath, UserData)) {
       // We've found a path that terminates at this base.
-      FoundPath = true;
+      FoundPath = FoundPathThroughBase = true;
       if (Paths.isRecordingPaths()) {
         // We have a path. Make a copy of it before moving on.
         Paths.Paths.push_back(Paths.ScratchPath);
@@ -240,7 +243,7 @@
         
         // There is a path to a base class that meets the criteria. If we're 
         // not collecting paths or finding ambiguities, we're done.
-        FoundPath = true;
+        FoundPath = FoundPathThroughBase = true;
         if (!Paths.isFindingAmbiguities())
           return FoundPath;
       }
@@ -253,7 +256,7 @@
     }
 
     // If we set a virtual earlier, and this isn't a path, forget it again.
-    if (SetVirtual && !FoundPath) {
+    if (SetVirtual && !FoundPathThroughBase) {
       Paths.DetectedVirtual = 0;
     }
   }

Added: cfe/trunk/test/CXX/conv/conv.mem/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/conv/conv.mem/p4.cpp?rev=95638&view=auto

==============================================================================
--- cfe/trunk/test/CXX/conv/conv.mem/p4.cpp (added)
+++ cfe/trunk/test/CXX/conv/conv.mem/p4.cpp Mon Feb  8 18:57:12 2010
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s
+
+struct Base {
+  int data;
+  int method();
+};
+int (Base::*data_ptr) = &Base::data;
+int (Base::*method_ptr)() = &Base::method;
+
+namespace test0 {
+  struct Derived : Base {};
+  void test() {
+    int (Derived::*d) = data_ptr;
+    int (Derived::*m)() = method_ptr;
+  }
+}
+
+// FIXME: can't be inaccessible.
+namespace test1 {
+  struct Derived : private Base {};
+  void test() {
+    int (Derived::*d) = data_ptr; // error
+    int (Derived::*m)() = method_ptr; // error
+  }
+};
+
+// Can't be ambiguous.
+namespace test2 {
+  struct A : Base {};
+  struct B : Base {};
+  struct Derived : A, B {};
+  void test() {
+    int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test2::Derived'}}
+    int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test2::Derived'}}
+  }
+}
+
+// Can't be virtual.
+namespace test3 {
+  struct Derived : virtual Base {};
+  void test() {
+    int (Derived::*d) = data_ptr;  // expected-error {{conversion from pointer to member of class 'struct Base' to pointer to member of class 'struct test3::Derived' via virtual base 'struct Base' is not allowed}}
+    int (Derived::*m)() = method_ptr; // expected-error {{conversion from pointer to member of class 'struct Base' to pointer to member of class 'struct test3::Derived' via virtual base 'struct Base' is not allowed}}
+  }
+}
+
+// Can't be virtual even if there's a non-virtual path.
+namespace test4 {
+  struct A : Base {};
+  struct Derived : Base, virtual A {};
+  void test() {
+    int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test4::Derived'}}
+    int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test4::Derived'}}
+  }
+}
+
+// PR6254: don't get thrown off by a virtual base.
+namespace test5 {
+  struct A {};
+  struct Derived : Base, virtual A {};
+  void test() {
+    int (Derived::*d) = data_ptr;
+    int (Derived::*m)() = method_ptr;
+  }
+}





More information about the cfe-commits mailing list