-
Notifications
You must be signed in to change notification settings - Fork 13.7k
fix access checking about function overloading #107768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
What's the status here? |
Sorry for the late response, I will continue to look into this issue this sunday. |
After some more debugging, I find out that we will check access here at llvm-project/clang/lib/Sema/SemaInit.cpp Line 7807 in 8e010ac
And for 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'}}
} |
65172d8
to
694b7dd
Compare
@llvm/pr-subscribers-clang Author: Zhikai Zeng (Backl1ght) Changesfix #107629 After some more debugging, I find out that we will check access here at llvm-project/clang/lib/Sema/SemaInit.cpp Line 7807 in 8e010ac
And for 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 I also test the UB mentioned in #107629 and clang now display 4 Full diff: https://github.com/llvm/llvm-project/pull/107768.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..0de249ced8309a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -763,6 +763,7 @@ Bug Fixes to C++ Support
- Fixed a bug where bounds of partially expanded pack indexing expressions were checked too early. (#GH116105)
- Fixed an assertion failure caused by using ``consteval`` in condition in consumed analyses. (#GH117385)
- Fix a crash caused by incorrect argument position in merging deduced template arguments. (#GH113659)
+- 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 4c9e37bd286dee..35389957adf32d 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -16305,6 +16305,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 ca98c9f90bd89e..6d4c8c004911db 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.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems reasonable to me? And passes tests?
The AS_none
has 'different meanings in different contexts, which is confusing here, so I have no idea what it is supposed to mean here. But unless someone has a problem with this, I suspect we should just see what the fallout of this is...
THOUGH, because I'm not sure, perhaps we wait another ~week for the branch and only do this in Clang21+?
DID a merge commit to see if we can get CI to approve this one, then I'll merge it (or someone else feel free to if you see it green!). |
fix llvm#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 llvm#107629 and clang now display 4 `false` as expecetd. Co-authored-by: Erich Keane <[email protected]>
fix llvm#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 llvm#107629 and clang now display 4 `false` as expecetd. Co-authored-by: Erich Keane <[email protected]>
fix #107629
After some more debugging, I find out that we will check access here at
llvm-project/clang/lib/Sema/SemaInit.cpp
Line 7807 in 8e010ac
And for
f()
inside code below,Found.getAccess()
isAS_none
henceCheckAddressOfMemberAccess
returnAR_accessible
directly.I think the
Found.getAccess()
is intended to beAS_none
so I just add one more access check for theUnresolvedLookupExpr
whenFound.getAccess()
isAS_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.