Selaa lähdekoodia

Fix diagnostic for access of protected/private base member. (#5874)

When importing the member, import the access level for the lookup
result, not the declared access of the member declaration.
Richard Smith 9 kuukautta sitten
vanhempi
sitoutus
a6f5143f22

+ 5 - 3
toolchain/check/import_cpp.cpp

@@ -1407,14 +1407,15 @@ static auto MapAccess(clang::AccessSpecifier access_specifier)
 static auto ImportNameDeclIntoScope(Context& context, SemIR::LocId loc_id,
                                     SemIR::NameScopeId scope_id,
                                     SemIR::NameId name_id,
-                                    clang::NamedDecl* clang_decl)
+                                    clang::NamedDecl* clang_decl,
+                                    clang::AccessSpecifier access)
     -> SemIR::ScopeLookupResult {
   SemIR::InstId inst_id =
       ImportDeclAndDependencies(context, loc_id, clang_decl);
   if (!inst_id.has_value()) {
     return SemIR::ScopeLookupResult::MakeNotFound();
   }
-  SemIR::AccessKind access_kind = MapAccess(clang_decl->getAccess());
+  SemIR::AccessKind access_kind = MapAccess(access);
   AddNameToScope(context, scope_id, name_id, access_kind, inst_id);
   return SemIR::ScopeLookupResult::MakeWrappedLookupResult(inst_id,
                                                            access_kind);
@@ -1447,7 +1448,8 @@ auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
   }
 
   return ImportNameDeclIntoScope(context, loc_id, scope_id, name_id,
-                                 lookup->getFoundDecl());
+                                 lookup->getFoundDecl(),
+                                 lookup->begin().getAccess());
 }
 
 }  // namespace Carbon::Check

+ 27 - 2
toolchain/check/testdata/interop/cpp/class/access.carbon

@@ -253,23 +253,48 @@ fn F() {
   //@dump-sem-ir-end
 }
 
-// --- todo_fail_import_base_class_protected.carbon
+// --- fail_import_base_class_protected.carbon
 
 library "[[@TEST_NAME]]";
 
 import Cpp library "base_class.h";
 
 fn F() {
+  // CHECK:STDERR: fail_import_base_class_protected.carbon:[[@LINE+5]]:3: error: cannot access protected member `foo` of type `Cpp.DerivedProtected` [ClassInvalidMemberAccess]
+  // CHECK:STDERR:   Cpp.DerivedProtected.foo();
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_import_base_class_protected.carbon: note: declared here [ClassMemberDeclaration]
+  // CHECK:STDERR:
   Cpp.DerivedProtected.foo();
 }
 
-// --- todo_fail_import_base_class_private.carbon
+// --- use_base_class_protected_from_derived.carbon
+
+library "[[@TEST_NAME]]";
+
+import Cpp library "base_class.h";
+
+class Derived {
+  extend base: Cpp.DerivedProtected;
+
+  fn F() {
+    // OK, we can access a protected member of our base class.
+    Cpp.DerivedProtected.foo();
+  }
+}
+
+// --- fail_import_base_class_private.carbon
 
 library "[[@TEST_NAME]]";
 
 import Cpp library "base_class.h";
 
 fn F() {
+  // CHECK:STDERR: fail_import_base_class_private.carbon:[[@LINE+5]]:3: error: cannot access private member `foo` of type `Cpp.DerivedPrivate` [ClassInvalidMemberAccess]
+  // CHECK:STDERR:   Cpp.DerivedPrivate.foo();
+  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~
+  // CHECK:STDERR: fail_import_base_class_private.carbon: note: declared here [ClassMemberDeclaration]
+  // CHECK:STDERR:
   Cpp.DerivedPrivate.foo();
 }