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] Immediate invocations in constexpr initailizers are evaluated twice #117321

Open
groundswellaudio opened this issue Nov 22, 2024 · 4 comments
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" consteval C++20 consteval constexpr Anything related to constant evaluation performance quality-of-implementation

Comments

@groundswellaudio
Copy link

It seems that immediate invocations in constexpr initailizers are evaluated twice, once on evaluating the decl, and again on Sema::HandleImmediateInvocations (this doesn't happen if the var is within a consteval function). Strictly speaking, not a defect, but it's kinda wasteful?

consteval int foo(int* b) {
    return *b; // Evaluation errors are emitted twice
}

constexpr int a = foo(nullptr); 

https://godbolt.org/z/7ec5bsK9e

@github-actions github-actions bot added the clang Clang issues not falling into any other category label Nov 22, 2024
@AaronBallman AaronBallman added quality-of-implementation performance clang:frontend Language frontend issues, e.g. anything involving "Sema" consteval C++20 consteval constexpr Anything related to constant evaluation and removed clang Clang issues not falling into any other category labels Nov 22, 2024
@AaronBallman
Copy link
Collaborator

Correct; we evaluate constant expressions multiple times in quite a few cases and I think we should be caching the results more aggressively.

@llvmbot
Copy link
Member

llvmbot commented Nov 22, 2024

@llvm/issue-subscribers-clang-frontend

Author: None (groundswellaudio)

It seems that immediate invocations in constexpr initailizers are evaluated twice, once on evaluating the decl, and again on Sema::HandleImmediateInvocations (this doesn't happen if the var is within a consteval function). Strictly speaking, not a defect, but it's kinda wasteful?
consteval int foo(int* b) {
    return *b; // Evaluation errors are emitted twice
}

constexpr int a = foo(nullptr); 

https://godbolt.org/z/7ec5bsK9e

@groundswellaudio
Copy link
Author

I think it might be possible to not add to the ImmediateInvocations set while in the initialiser of a constexpr variable.

@efriedma-quic
Copy link
Collaborator

In some cases, the "evaluate twice" semantics are required by the standard, and I'd rather keep the parsing as unified as possible. See also #89565. (Note the semantics are slightly different in C++23 mode.)

Probably the answer here is to just tweak the way error recovery works: we should treat initializers for constexpr variables as an immediate function context even if evaluation produces an error, so we don't get redundant error messages.

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" consteval C++20 consteval constexpr Anything related to constant evaluation performance quality-of-implementation
Projects
None yet
Development

No branches or pull requests

4 participants