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

[clang][rejects valid][c++20] bad parse of constrained friend function #83461

Closed
ericniebler opened this issue Feb 29, 2024 · 8 comments
Closed
Assignees
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party rejects-valid

Comments

@ericniebler
Copy link

The following should compile (-std=c++20):

template <class A>
concept always_true = true;

struct receiver {
  template <class Tag = int>
  friend void tag_invoke( always_true auto, receiver self) {
  }
};

All recent versions of clang including trunk rejects this code with:

<source>:9:43: error: template parameter missing a default argument
    9 |   friend void tag_invoke( always_true auto, receiver self) {
      |                                           ^
<source>:8:25: note: previous default template argument defined here
    8 |   template <class Tag = int>
      |                         ^
1 error generated.
Compiler returned: 1

https://godbolt.org/z/6G1hPsKM3

@github-actions github-actions bot added the clang Clang issues not falling into any other category label Feb 29, 2024
@EugeneZelenko EugeneZelenko added c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid and removed clang Clang issues not falling into any other category labels Feb 29, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 29, 2024

@llvm/issue-subscribers-clang-frontend

Author: Eric Niebler (ericniebler)

The following should compile (-std=c++20):
template &lt;class A&gt;
concept always_true = true;

struct receiver {
  template &lt;class Tag = int&gt;
  friend void tag_invoke( always_true auto, receiver self) {
  }
};

All recent versions of clang including trunk rejects this code with:

&lt;source&gt;:9:43: error: template parameter missing a default argument
    9 |   friend void tag_invoke( always_true auto, receiver self) {
      |                                           ^
&lt;source&gt;:8:25: note: previous default template argument defined here
    8 |   template &lt;class Tag = int&gt;
      |                         ^
1 error generated.
Compiler returned: 1

https://godbolt.org/z/6G1hPsKM3

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 29, 2024

@llvm/issue-subscribers-c-20

Author: Eric Niebler (ericniebler)

The following should compile (-std=c++20):
template &lt;class A&gt;
concept always_true = true;

struct receiver {
  template &lt;class Tag = int&gt;
  friend void tag_invoke( always_true auto, receiver self) {
  }
};

All recent versions of clang including trunk rejects this code with:

&lt;source&gt;:9:43: error: template parameter missing a default argument
    9 |   friend void tag_invoke( always_true auto, receiver self) {
      |                                           ^
&lt;source&gt;:8:25: note: previous default template argument defined here
    8 |   template &lt;class Tag = int&gt;
      |                         ^
1 error generated.
Compiler returned: 1

https://godbolt.org/z/6G1hPsKM3

@shafik
Copy link
Collaborator

shafik commented Feb 29, 2024

Confirmed: https://godbolt.org/z/96Y4e4j1r

I don't know what is going on here, maybe @erichkeane does

@shafik shafik added the confirmed Verified by a second party label Feb 29, 2024
@erichkeane
Copy link
Collaborator

erichkeane commented Feb 29, 2024

I've never seen that error before... At least it doesn't have anything to do with concepts (reduced away as:

struct receiver {
  template <class Tag = int>
  friend void tag_invoke(  auto, receiver self) {
  }
};

My guess is that we're somehow ordering the 'auto' parameter 'last' in template argument ordering rather than 'first'. I'm not sure what the CORRECT answer is there though, and wonder if this is either a CWG issue-worthy thing, or just a clang bug (Can anyone find some prose that gives explaination here?).

But effectively what it looks like is happening is that our check to prevent this pattern:

struct receiver {
  template <class Tag = int, class T2>
  friend void tag_invoke(receiver self) {
  }
};

Is picking up the 'auto' parameter.

@erichkeane
Copy link
Collaborator

Side note, we don't seem to have this problem with Lambdas, so figuring out what we do differently there might be informative: https://godbolt.org/z/1WzdWvKK3

@erichkeane
Copy link
Collaborator

OH! Strangly it is ONLY in the case of a friend function, free/member function aren't affected either for some reason.

@erichkeane
Copy link
Collaborator

Ah, figured it out... all my speculation was wrong! Its an incorrect implementation of

https://eel.is/c++draft/temp.param#14

WIP now.

erichkeane added a commit to erichkeane/llvm-project that referenced this issue Feb 29, 2024
The first sentence says:

If a template-parameter of a class template, variable template, or alias
template has a default template-argument, each subsequent
template-parameter shall either have a default template-argument
supplied or be a template parameter pack.

However, we were only testing for "not a function function template",
and referring to an older version of the standard.  As far as I can
tell, CWG2032 added the variable-template, and the alias-template
pre-dates the standard on github.

This patch started as a bug fix for llvm#83461 , but ended up fixing a
number of similar cases, so those are validated as well.
@erichkeane erichkeane self-assigned this Feb 29, 2024
erichkeane added a commit that referenced this issue Mar 1, 2024
The first sentence says:

If a template-parameter of a class template, variable template, or alias
template has a default template-argument, each subsequent
template-parameter shall either have a default template-argument
supplied or be a template parameter pack.

However, we were only testing for "not a function function template",
and referring to an older version of the standard. As far as I can tell,
CWG2032 added the variable-template, and the alias-template pre-dates
the standard on github.

This patch started as a bug fix for #83461 , but ended up fixing a
number of similar cases, so those are validated as well.
@ericniebler
Copy link
Author

Thank you for the speedy fix!

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" confirmed Verified by a second party rejects-valid
Projects
Status: Done
Development

No branches or pull requests

5 participants