Skip to content
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

Wrong specialization becomes friend as checked by requires-expression #53364

Closed
Fedr opened this issue Jan 23, 2022 · 2 comments
Closed

Wrong specialization becomes friend as checked by requires-expression #53364

Fedr opened this issue Jan 23, 2022 · 2 comments
Assignees
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts

Comments

@Fedr
Copy link

Fedr commented Jan 23, 2022

In the following code, there is template struct A with not-type template argument, and class B declares A<0> as its friend. Then the member function A<x>::has_access() is used to check that it has access to private B::p():

template<auto>
struct A {
    static constexpr bool has_access();
};

class B {
    void p() {}
    friend struct A<0>;
};

template<auto x>
constexpr bool A<x>::has_access() {
    return requires(B b) { b.p(); };
}

static_assert( !A<1>::has_access() );

And in Clang A<1> gets access to private fields of B. Not so in other compilers. Demo: https://gcc.godbolt.org/z/f7qPo6fnj

Related discussion: https://stackoverflow.com/q/70812488/7325599

@zero9178 zero9178 added c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts and removed new issue labels Jan 23, 2022
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 23, 2022

@llvm/issue-subscribers-c-20

@llvmbot
Copy link
Collaborator

llvmbot commented Jan 23, 2022

@llvm/issue-subscribers-clang-frontend

@usx95 usx95 assigned usx95 and unassigned gislan Dec 20, 2022
@usx95 usx95 closed this as completed in 9e0474f Jan 11, 2023
CarlosAlbertoEnciso pushed a commit to SNSystems/llvm-debuginfo-analyzer that referenced this issue Jan 12, 2023
> Dependent access checks.

Fixes: llvm/llvm-project#53364

We previously ignored dependent access checks to private members.
These are visible only to the `RequiresExprBodyExpr` (through `PerformDependentDiagnositcs`) and not to the individual requirements.

---

> Non-dependent access checks.
Fixes: llvm/llvm-project#53334
Access to members in a non-dependent context would always yield an
invalid expression. When it appears in a requires-expression, then this
is a hard error as this would always result in a substitution failure.

https://eel.is/c++draft/expr.prim.req#general-note-1
> Note 1: If a requires-expression contains invalid types or expressions in its requirements, and it does not appear within the declaration of a templated entity, then the program is ill-formed. — end note]
> If the substitution of template arguments into a requirement would always result in a substitution failure, the program is ill-formed; no diagnostic required.

The main issue here is the delaying of the diagnostics.
Use a `ParsingDeclRAIIObject` creates a separate diagnostic pool for diagnositcs associated to the `RequiresExprBodyDecl`.
This is important because dependent diagnostics should not be leaked/delayed to higher scopes (Eg. inside a template function or in a trailing requires). These dependent diagnostics must be attached to the `DeclContext` of the parameters of `RequiresExpr` (which is the `RequiresExprBodyDecl` in this case).
Non dependent diagnostics, on the other hand, should not delayed and surfaced as hard errors.

Differential Revision: https://reviews.llvm.org/D140547
veselypeta pushed a commit to veselypeta/cherillvm that referenced this issue Jun 12, 2024
> Dependent access checks.

Fixes: llvm/llvm-project#53364

We previously ignored dependent access checks to private members.
These are visible only to the `RequiresExprBodyExpr` (through `PerformDependentDiagnositcs`) and not to the individual requirements.

---

> Non-dependent access checks.
Fixes: llvm/llvm-project#53334
Access to members in a non-dependent context would always yield an
invalid expression. When it appears in a requires-expression, then this
is a hard error as this would always result in a substitution failure.

https://eel.is/c++draft/expr.prim.req#general-note-1
> Note 1: If a requires-expression contains invalid types or expressions in its requirements, and it does not appear within the declaration of a templated entity, then the program is ill-formed. — end note]
> If the substitution of template arguments into a requirement would always result in a substitution failure, the program is ill-formed; no diagnostic required.

The main issue here is the delaying of the diagnostics.
Use a `ParsingDeclRAIIObject` creates a separate diagnostic pool for diagnositcs associated to the `RequiresExprBodyDecl`.
This is important because dependent diagnostics should not be leaked/delayed to higher scopes (Eg. inside a template function or in a trailing requires). These dependent diagnostics must be attached to the `DeclContext` of the parameters of `RequiresExpr` (which is the `RequiresExprBodyDecl` in this case).
Non dependent diagnostics, on the other hand, should not delayed and surfaced as hard errors.

Differential Revision: https://reviews.llvm.org/D140547
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts
Projects
Status: Done
Development

No branches or pull requests

5 participants