Author: Zhikai Zeng Date: 2025-06-10T11:50:22-07:00 New Revision: 46b7a88548e5016f403cdc5f2cb1e4ff09353c3b
URL: https://github.com/llvm/llvm-project/commit/46b7a88548e5016f403cdc5f2cb1e4ff09353c3b DIFF: https://github.com/llvm/llvm-project/commit/46b7a88548e5016f403cdc5f2cb1e4ff09353c3b.diff LOG: fix access checking about function overloading (#107768) fix https://github.com/llvm/llvm-project/issues/107629 After some more debugging, I find out that we will check access here at https://github.com/llvm/llvm-project/blob/8e010ac5a173c9dee44b44324169a3e100a1a6fc/clang/lib/Sema/SemaInit.cpp#L7807 And for `f()` inside code below, `Found.getAccess()` is `AS_none` hence `CheckAddressOfMemberAccess` return `AR_accessible` directly. ```cpp struct Base { public: int f(int); private: int f(); // expect-note {{declared private here}} }; struct Derived : public Base {}; void f() { int(Derived::* public_f)(int) = &Derived::f; int(Derived::* private_f)() = &Derived::f; // expect-error {{'f' is a private member of 'Base'}} } ``` I think the `Found.getAccess()` is intended to be `AS_none` so I just add one more access check for the `UnresolvedLookupExpr` when `Found.getAccess()` is `AS_none`. If add the check unconditionally clang will report lots of duplicate errors and cause several unit tests to fail. I also test the UB mentioned in https://github.com/llvm/llvm-project/issues/107629 and clang now display 4 `false` as expecetd. Co-authored-by: Erich Keane <eke...@nvidia.com> Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaOverload.cpp clang/test/CXX/class.access/p4.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index beed0da6883d6..f36c82bff2ef8 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -840,6 +840,7 @@ Bug Fixes to C++ Support - Fixed a pack substitution bug in deducing class template partial specializations. (#GH53609) - Fixed a crash when constant evaluating some explicit object member assignment operators. (#GH142835) - Fixed an access checking bug when substituting into concepts (#GH115838) +- Fix a bug where private access specifier of overloaded function not respected. (#GH107629) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 5a19dacdc4d84..cf455f4588de3 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -16981,6 +16981,9 @@ ExprResult Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, } if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) { + if (Found.getAccess() == AS_none) { + CheckUnresolvedLookupAccess(ULE, Found); + } // FIXME: avoid copy. TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr; if (ULE->hasExplicitTemplateArgs()) { diff --git a/clang/test/CXX/class.access/p4.cpp b/clang/test/CXX/class.access/p4.cpp index ca98c9f90bd89..6d4c8c004911d 100644 --- a/clang/test/CXX/class.access/p4.cpp +++ b/clang/test/CXX/class.access/p4.cpp @@ -21,11 +21,13 @@ namespace test0 { public: void foo(Public&); protected: - void foo(Protected&); // expected-note 2 {{declared protected here}} + void foo(Protected&); // expected-note 4 {{declared protected here}} private: - void foo(Private&); // expected-note 2 {{declared private here}} + void foo(Private&); // expected-note 4 {{declared private here}} }; + class B : public A {}; + void test(A *op) { op->foo(PublicInst); op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}} @@ -35,6 +37,16 @@ namespace test0 { void (A::*b)(Protected&) = &A::foo; // expected-error {{'foo' is a protected member}} void (A::*c)(Private&) = &A::foo; // expected-error {{'foo' is a private member}} } + + void test(B *op) { + op->foo(PublicInst); + op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}} + op->foo(PrivateInst); // expected-error {{'foo' is a private member}} + + void (B::*a)(Public&) = &B::foo; + void (B::*b)(Protected&) = &B::foo; // expected-error {{'foo' is a protected member}} + void (B::*c)(Private&) = &B::foo; // expected-error {{'foo' is a private member}} + } } // Member operators. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits