Too aggresive C++23 static call operator optimization (original) (raw)

Hello,

It looks like clang is too aggressive for C++23 static call optimization. Here is the simplified example of real code:

#include #include

template struct Wrapper { template <typename F, typename... Args> static void operator()(F&& callable, Args&&... args) { Invoke(std::forward(callable), std::forward(args)...); }

template <typename F, typename... Args>
static void Invoke(F&& callable, Args&&... args) {
    std::invoke(std::forward<F>(callable), std::forward<Args>(args)...);
}

};

struct Manager { template static SingletonClass& Get() { std::cout << "get call\n"; static SingletonClass instance; return instance; } };

struct Tag {};

int main() { using TaggedWrapper = Wrapper; Manager::Get()([] { std::cout << "Function\n"; }); }

We assume that Manager::Get() will be called and get call will be printed, but it doesn't happen. If change call in main to Manager::Get<TaggedWrapper>().Invoke([] { std::cout << "Function\n"; }); it works as expected. get cal also will be printed if remove static from operator(). It reproducible even with -O0. clang-17.0.1