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

lambda call should propagate as immediate function when the body is immediate-escalating expression #92547

Open
changkhothuychung opened this issue May 17, 2024 · 4 comments
Labels
clang:codegen lambda C++11 lambda expressions

Comments

@changkhothuychung
Copy link
Contributor

Should clang not generate the lambda call operator for this lambda call?

According to https://eel.is/c++draft/expr.const#18, the call operator of a lambda that is not declared with the consteval specifier is an immediate-escalating function (1)

From https://eel.is/c++draft/expr.const#17, the call to f() is an immediate-escalating expression. (2)

(1) and (2) will make the call to l() an immediate function and assembly code should not generate assembly code for the call operator. gcc seems to do it

consteval auto f()
{
    return 1; 
}

auto l = [](){
    return f(); 
};


int main()
{
    auto x = l();
}

https://godbolt.org/z/vn6fh1fE5

@MitalAshok
Copy link
Contributor

The lack of code gen with GCC is an optimization. GCC still also allows auto lp = &decltype(l)::operator();, showing that l's call operator is not marked consteval in GCC too.

This should be the expected behaviour as f() is an immediate invocation that is a constant expression in its own right, so it's not immediate-escalating (https://eel.is/c++draft/expr.const#17.2)

@EugeneZelenko EugeneZelenko added clang:codegen lambda C++11 lambda expressions and removed new issue labels May 17, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented May 17, 2024

@llvm/issue-subscribers-clang-codegen

Author: Nhat Nguyen (changkhothuychung)

Should clang not generate the lambda call operator for this lambda call?

According to https://eel.is/c++draft/expr.const#18, the call operator of a lambda that is not declared with the consteval specifier is an immediate-escalating function (1)

From https://eel.is/c++draft/expr.const#17, the call to f() is an immediate-escalating expression. (2)

(1) and (2) will make the call to l() an immediate function and assembly code should not generate assembly code for the call operator. gcc seems to do it

consteval auto f()
{
    return 1; 
}

auto l = [](){
    return f(); 
};


int main()
{
    auto x = l();
}

https://godbolt.org/z/vn6fh1fE5

@changkhothuychung
Copy link
Contributor Author

The lack of code gen with GCC is an optimization. GCC still also allows auto lp = &decltype(l)::operator();, showing that l's call operator is not marked consteval in GCC too.

This should be the expected behaviour as f() is an immediate invocation that is a constant expression in its own right, so it's not immediate-escalating (https://eel.is/c++draft/expr.const#17.2)

Oh right. Now I think more about it, can you give me an example which is an immediate invocation and not a constant expression? I missed the constant expression part when I created this issue, and now I cant think of one example. Thanks!

@MitalAshok
Copy link
Contributor

@changkhothuychung https://godbolt.org/z/doYzMMKb6

consteval auto f(int) {
    return 1; 
}

auto l = [](int i) {
    return f(i);  // Change to "f(0)" and it's no longer immediate-escalating
};

int main() {
    auto x = l(0);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen lambda C++11 lambda expressions
Projects
None yet
Development

No branches or pull requests

4 participants