Skip to content

Commit 46b7a88

Browse files
fix access checking about function overloading (#107768)
fix #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 #107629 and clang now display 4 `false` as expecetd. Co-authored-by: Erich Keane <[email protected]>
1 parent 4e706ad commit 46b7a88

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,7 @@ Bug Fixes to C++ Support
840840
- Fixed a pack substitution bug in deducing class template partial specializations. (#GH53609)
841841
- Fixed a crash when constant evaluating some explicit object member assignment operators. (#GH142835)
842842
- Fixed an access checking bug when substituting into concepts (#GH115838)
843+
- Fix a bug where private access specifier of overloaded function not respected. (#GH107629)
843844

844845
Bug Fixes to AST Handling
845846
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaOverload.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16981,6 +16981,9 @@ ExprResult Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
1698116981
}
1698216982

1698316983
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
16984+
if (Found.getAccess() == AS_none) {
16985+
CheckUnresolvedLookupAccess(ULE, Found);
16986+
}
1698416987
// FIXME: avoid copy.
1698516988
TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
1698616989
if (ULE->hasExplicitTemplateArgs()) {

clang/test/CXX/class.access/p4.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ namespace test0 {
2121
public:
2222
void foo(Public&);
2323
protected:
24-
void foo(Protected&); // expected-note 2 {{declared protected here}}
24+
void foo(Protected&); // expected-note 4 {{declared protected here}}
2525
private:
26-
void foo(Private&); // expected-note 2 {{declared private here}}
26+
void foo(Private&); // expected-note 4 {{declared private here}}
2727
};
2828

29+
class B : public A {};
30+
2931
void test(A *op) {
3032
op->foo(PublicInst);
3133
op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}}
@@ -35,6 +37,16 @@ namespace test0 {
3537
void (A::*b)(Protected&) = &A::foo; // expected-error {{'foo' is a protected member}}
3638
void (A::*c)(Private&) = &A::foo; // expected-error {{'foo' is a private member}}
3739
}
40+
41+
void test(B *op) {
42+
op->foo(PublicInst);
43+
op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}}
44+
op->foo(PrivateInst); // expected-error {{'foo' is a private member}}
45+
46+
void (B::*a)(Public&) = &B::foo;
47+
void (B::*b)(Protected&) = &B::foo; // expected-error {{'foo' is a protected member}}
48+
void (B::*c)(Private&) = &B::foo; // expected-error {{'foo' is a private member}}
49+
}
3850
}
3951

4052
// Member operators.

0 commit comments

Comments
 (0)