| Issue |
114755
|
| Summary |
[clang][regression] lambda call in unevaluated context in generic lambda in template function fails from clang 15 onwards
|
| Labels |
clang
|
| Assignees |
|
| Reporter |
wanghan02
|
Example code could be found below or on [godbolt](https://godbolt.org/z/crefWM4MY). clang 14, gcc and MSVC all compile fine. clang 15 onwards fail.
The problem is triggered only if `tc_lazy` is called in a template function and the lambda in `tc_lazy` is a generic lambda.
```
#include <type_traits>
#include <utility>
#define HYBRIDSTR(str) \
[](auto t) constexpr noexcept -> decltype(auto) { \
using ArgCharT = typename decltype(t)::type; \
if constexpr(std::is_same<ArgCharT, char>::value) { \
return str; \
} else if constexpr(std::is_same<ArgCharT, wchar_t>::value) { \
return L ## str; \
} else if constexpr(std::is_same<ArgCharT, char16_t>::value) { \
return u ## str; \
} else { \
static_assert(std::is_same<ArgCharT, char32_t>::value); \
return U ## str; \
} \
}
namespace tc {
template<typename T>
constexpr std::conditional_t<
std::is_rvalue_reference<T&&>::value,
std::decay_t<T>,
T
> lvalue_or_decay(T&& t) {
return std::forward<T>(t);
}
namespace make_lazy_adl {
template<typename Func>
struct make_lazy : Func {
constexpr explicit make_lazy(Func func) noexcept : Func(std::move(func)) {}
constexpr operator decltype(std::declval<Func const&>()())() const&& {
return (*this)();
}
};
}
using make_lazy_adl::make_lazy;
namespace lazy_detail {
template<bool bReference, typename T>
decltype(auto) lvalue_or_decay(T&& t) noexcept {
if constexpr (bReference) {
return tc::lvalue_or_decay(std::forward<T>(t));
}
}
}
}
#define tc_lazy( ... ) tc::make_lazy([&](auto&&...) -> decltype(auto) { \
if constexpr (std::is_reference<decltype((__VA_ARGS__))>::value) { \
return tc::lazy_detail::lvalue_or_decay<std::is_reference<decltype((__VA_ARGS__))>::value>(__VA_ARGS__); \
} else { \
return __VA_ARGS__; \
} \
})
template<typename Char>
auto foo() {
return tc_lazy(HYBRIDSTR("abc")(std::type_identity<Char>()))(); // fails in template function from clang 15 onwards
}
void bar() {
tc_lazy(0)();
tc_lazy(HYBRIDSTR("abc")(std::type_identity<char16_t>()))(); // compiles
foo<char16_t>();
}
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs