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

Entire lambda body is printed in a note #125914

Open
Endilll opened this issue Feb 5, 2025 · 7 comments
Open

Entire lambda body is printed in a note #125914

Endilll opened this issue Feb 5, 2025 · 7 comments
Assignees
Labels
c++ clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer good first issue https://github.com/llvm/llvm-project/contribute

Comments

@Endilll
Copy link
Contributor

Endilll commented Feb 5, 2025

Consider the following example (https://godbolt.org/z/P7dqa81bG):

class S {
  class Incomplete;

  struct Inner {
    consteval void fn() {
      Incomplete i;
    }
  };

  static constexpr int r = [] {
    Inner{}.fn();
    return 0;
  }();

  class Incomplete {};
};

We issue the following diagnostics for it:

<source>:10:28: error: call to immediate function 'S::(anonymous class)::operator()' is not a constant expression
   10 |   static constexpr int r = [] {
      |                            ^
<source>:11:13: note: undefined function 'fn' cannot be used in a constant expression
   11 |     Inner{}.fn();
      |             ^
<source>:10:28: note: in call to '[] {
    Inner{}.fn();
    return 0;
}.operator()()'
   10 |   static constexpr int r = [] {
      |                            ^~~~
   11 |     Inner{}.fn();
      |     ~~~~~~~~~~~~~
   12 |     return 0;
      |     ~~~~~~~~~
   13 |   }();
      |   ~~~
<source>:5:20: note: declared here
    5 |     consteval void fn() {
      |                    ^
<source>:10:24: error: constexpr variable 'r' must be initialized by a constant expression
   10 |   static constexpr int r = [] {
      |                        ^   ~~~~
   11 |     Inner{}.fn();
      |     ~~~~~~~~~~~~~
   12 |     return 0;
      |     ~~~~~~~~~
   13 |   }();
      |   ~~~
<source>:11:13: note: undefined function 'fn' cannot be used in a constant expression
   11 |     Inner{}.fn();
      |             ^
<source>:10:28: note: in call to '[] {
    Inner{}.fn();
    return 0;
}.operator()()'
   10 |   static constexpr int r = [] {
      |                            ^~~~
   11 |     Inner{}.fn();
      |     ~~~~~~~~~~~~~
   12 |     return 0;
      |     ~~~~~~~~~
   13 |   }();
      |   ~~~
<source>:5:20: note: declared here
    5 |     consteval void fn() {
      |                    ^
2 errors generated.

It seems unfortunate that multi-line lambda body gets printed in the in call to note.

@Endilll Endilll added c++ clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer and removed new issue labels Feb 5, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 5, 2025

@llvm/issue-subscribers-c-1

Author: Vlad Serebrennikov (Endilll)

Consider the following example (https://godbolt.org/z/P7dqa81bG): ```cpp class S { class Incomplete;

struct Inner {
consteval void fn() {
Incomplete i;
}
};

static constexpr int r = [] {
Inner{}.fn();
return 0;
}();

class Incomplete {};
};

We issue the following diagnostics for it:

<source>:10:28: error: call to immediate function 'S::(anonymous class)::operator()' is not a constant expression
10 | static constexpr int r = [] {
| ^
<source>:11:13: note: undefined function 'fn' cannot be used in a constant expression
11 | Inner{}.fn();
| ^
<source>:10:28: note: in call to '[] {
Inner{}.fn();
return 0;
}.operator()()'
10 | static constexpr int r = [] {
| ^~~~
11 | Inner{}.fn();
| ~~~~~~~~~~~~~
12 | return 0;
| ~~~~~~~~~
13 | }();
| ~~~
<source>:5:20: note: declared here
5 | consteval void fn() {
| ^
<source>:10:24: error: constexpr variable 'r' must be initialized by a constant expression
10 | static constexpr int r = [] {
| ^ ~~~~
11 | Inner{}.fn();
| ~~~~~~~~~~~~~
12 | return 0;
| ~~~~~~~~~
13 | }();
| ~~~
<source>:11:13: note: undefined function 'fn' cannot be used in a constant expression
11 | Inner{}.fn();
| ^
<source>:10:28: note: in call to '[] {
Inner{}.fn();
return 0;
}.operator()()'
10 | static constexpr int r = [] {
| ^~~~
11 | Inner{}.fn();
| ~~~~~~~~~~~~~
12 | return 0;
| ~~~~~~~~~
13 | }();
| ~~~
<source>:5:20: note: declared here
5 | consteval void fn() {
| ^
2 errors generated.

It seems unfortunate that multi-line lambda body gets printed in the `in call to` note.
</details>

@cor3ntin cor3ntin added the good first issue https://github.com/llvm/llvm-project/contribute label Feb 5, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 5, 2025

Hi!

This issue may be a good introductory issue for people new to working on LLVM. If you would like to work on this issue, your first steps are:

  1. Check that no other contributor has already been assigned to this issue. If you believe that no one is actually working on it despite an assignment, ping the person. After one week without a response, the assignee may be changed.
  2. In the comments of this issue, request for it to be assigned to you, or just create a pull request after following the steps below. Mention this issue in the description of the pull request.
  3. Fix the issue locally.
  4. Run the test suite locally. Remember that the subdirectories under test/ create fine-grained testing targets, so you can e.g. use make check-clang-ast to only run Clang's AST tests.
  5. Create a Git commit.
  6. Run git clang-format HEAD~1 to format your changes.
  7. Open a pull request to the upstream repository on GitHub. Detailed instructions can be found in GitHub's documentation. Mention this issue in the description of the pull request.

If you have any further questions about this issue, don't hesitate to ask via a comment in the thread below.

@llvmbot
Copy link
Member

llvmbot commented Feb 5, 2025

@llvm/issue-subscribers-good-first-issue

Author: Vlad Serebrennikov (Endilll)

Consider the following example (https://godbolt.org/z/P7dqa81bG): ```cpp class S { class Incomplete;

struct Inner {
consteval void fn() {
Incomplete i;
}
};

static constexpr int r = [] {
Inner{}.fn();
return 0;
}();

class Incomplete {};
};

We issue the following diagnostics for it:

<source>:10:28: error: call to immediate function 'S::(anonymous class)::operator()' is not a constant expression
10 | static constexpr int r = [] {
| ^
<source>:11:13: note: undefined function 'fn' cannot be used in a constant expression
11 | Inner{}.fn();
| ^
<source>:10:28: note: in call to '[] {
Inner{}.fn();
return 0;
}.operator()()'
10 | static constexpr int r = [] {
| ^~~~
11 | Inner{}.fn();
| ~~~~~~~~~~~~~
12 | return 0;
| ~~~~~~~~~
13 | }();
| ~~~
<source>:5:20: note: declared here
5 | consteval void fn() {
| ^
<source>:10:24: error: constexpr variable 'r' must be initialized by a constant expression
10 | static constexpr int r = [] {
| ^ ~~~~
11 | Inner{}.fn();
| ~~~~~~~~~~~~~
12 | return 0;
| ~~~~~~~~~
13 | }();
| ~~~
<source>:11:13: note: undefined function 'fn' cannot be used in a constant expression
11 | Inner{}.fn();
| ^
<source>:10:28: note: in call to '[] {
Inner{}.fn();
return 0;
}.operator()()'
10 | static constexpr int r = [] {
| ^~~~
11 | Inner{}.fn();
| ~~~~~~~~~~~~~
12 | return 0;
| ~~~~~~~~~
13 | }();
| ~~~
<source>:5:20: note: declared here
5 | consteval void fn() {
| ^
2 errors generated.

It seems unfortunate that multi-line lambda body gets printed in the `in call to` note.
</details>

@cor3ntin
Copy link
Contributor

cor3ntin commented Feb 5, 2025

in ExprConstant.cpp

 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
        << DiagDecl->isConstexpr() << (bool)CD << DiagDecl;
    Info.Note(DiagDecl->getLocation(), diag::note_declared_at);

DiagDecl needs to be changed to be the lambda if it is the call operator of a lambda, or something along these lines.
It might be worth looking how we print lambdas in other places

@a-tarasyuk a-tarasyuk assigned a-tarasyuk and unassigned a-tarasyuk Feb 5, 2025
@ajayrajsaini
Copy link
Contributor

Hey @Endilll , @a-tarasyuk , @cor3ntin
is this issue still open if it is i will love to work on this

@a-tarasyuk
Copy link
Member

@ajayrajsaini yes, it's still open. I've assigned it to you. thanks

@ajayrajsaini
Copy link
Contributor

ajayrajsaini commented Feb 17, 2025

hey @cor3ntin i added these lines based on your suggestion:-

if (auto *MD = dyn_cast<CXXMethodDecl>(DiagDecl)) {
        if (MD->getParent()->isLambda()) {
          DiagDecl = MD->getParent();  // Use the lambda instead of its operator
        }
      }

but still i found no changes when i am compiling it ( i am using this to compile:- clang -nostdinc -nostdlib hello.cpp -I libc/include -I $(clang -print-resource-dir)/include libc/startup/linux/crt1.o libc/lib/libc.a)

can you help me a little weather i am on right direction or not and what should be the output.

cc:- @a-tarasyuk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer good first issue https://github.com/llvm/llvm-project/contribute
Projects
None yet
Development

No branches or pull requests

5 participants