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

explicit template instantiation wrongly checks decomposition of private members #80410

Open
schaumb opened this issue Feb 2, 2024 · 6 comments
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema"

Comments

@schaumb
Copy link

schaumb commented Feb 2, 2024

The following code does not compile:

template<class T, class Mb>
struct First { void f(); };

struct A {
    A();
private:
    int a; // probably not this easy to calculate the first member's type.
    int b;
}; 


// compilation unit 1
A::A() {
    // can use decomposition
    First<A, decltype(+[] (A &v) -> decltype(auto) { auto& [x, y] = v; return x; })> f1; 
    f1.f();
}


// compilation unit 2
template<class T, class Mb>
void First<T, Mb>::f() {}

template struct First<A, decltype(+[] (A &v) -> decltype(auto) { auto& [x, y] = v; return x; })>; // error

It should based on the C++ standard: https://eel.is/c++draft/temp.spec#general-6

<source>:25:73: error: cannot decompose private member 'a' of 'A'
   25 | template struct First<A, decltype(+[] (A &v) -> decltype(auto) { auto& [x, y] = v; return x; })>;

godbolt

@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed new issue labels Feb 2, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 2, 2024

@llvm/issue-subscribers-clang-frontend

Author: Bela Schaum (schaumb)

The following code does not compile:
template&lt;class T, class Mb&gt;
struct First { void f(); };

struct A {
    A();
private:
    int a; // probably not this easy to calculate the first member's type.
    int b;
}; 


// compilation unit 1
A::A() {
    // can use decomposition
    First&lt;A, decltype(+[] (A &amp;v) -&gt; decltype(auto) { auto&amp; [x, y] = v; return x; })&gt; f1; 
    f1.f();
}


// compilation unit 2
template&lt;class T, class Mb&gt;
void First&lt;T, Mb&gt;::f() {}

template struct First&lt;A, decltype(+[] (A &amp;v) -&gt; decltype(auto) { auto&amp; [x, y] = v; return x; })&gt;; // error

It should based on the C++ standard: https://eel.is/c++draft/temp.spec#general-6

&lt;source&gt;:25:73: error: cannot decompose private member 'a' of 'A'
   25 | template struct First&lt;A, decltype(+[] (A &amp;v) -&gt; decltype(auto) { auto&amp; [x, y] = v; return x; })&gt;;

godbolt

@shafik
Copy link
Collaborator

shafik commented Feb 3, 2024

Note no implementation accepts this code as well-formed: https://godbolt.org/z/x5brEYsW4

and this is expected as per dcl.struct.bind p5 which says:

Otherwise, all of E's non-static data members shall be direct members of E or of the same base class of E, well-formed when named as e.name in the context of the structured binding ...

v.a is not well-formed in this context since it is private and not accessible. In the first case it is within a member of A and this accessible.

@shafik shafik closed this as not planned Won't fix, can't repro, duplicate, stale Feb 3, 2024
@EugeneZelenko EugeneZelenko added the invalid Resolved as invalid, i.e. not a bug label Feb 3, 2024
@schaumb
Copy link
Author

schaumb commented Feb 3, 2024

@shafik
I disagree with this argument, because v.a is well formed, see that this is compiling:

// compilation unit 1
A::A() {
    First<A, decltype(+[] (A &v) -> decltype(auto) { return v.a; })> f1;
    f1.f();
}

// compilation unit 2
template<class T, class Mb>
void First<T, Mb>::f() {}

template struct First<A, decltype(+[] (A &v) -> decltype(auto) { return v.a; })>;

As I linked, The usual access checking rules do not apply to names in a declaration of an explicit instantiation or explicit specialization

Please reopen the issue.

@shafik
Copy link
Collaborator

shafik commented Feb 3, 2024

CC @zygoloid do you believe this was meant to be supported?

It looks like it came in via: https://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0692r1.html

but it is pretty bare bones wrt examples.

The second examples the OP provided has mixed support: https://godbolt.org/z/1v4zq5a3T

@schaumb
Copy link
Author

schaumb commented Feb 3, 2024

Gcc has another problem: it cannot accept lambdas as template instantiation, but when lambda is not at the declaration level, it accepts it.

msvc has many other bugs with the template instantiation, as this and this

@schaumb
Copy link
Author

schaumb commented Feb 6, 2024

@shafik can you reopen it until a final decision is made?

@cor3ntin cor3ntin reopened this Feb 6, 2024
@EugeneZelenko EugeneZelenko removed the invalid Resolved as invalid, i.e. not a bug label Feb 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema"
Projects
None yet
Development

No branches or pull requests

5 participants