Open llvmbot opened 6 years ago
This is still being rejected with post 17 trunk(cf7d4f543c73c2707e0c53bae1e7b8419e12b871) https://godbolt.org/z/rGvqfjYTP
I have simplified the code a bit.
The code will compile fine if either the argument type of the lambda is specified, or the return type of the lambda is not specified.
code
// compile with -std=c++17
template<typename F>
constexpr int func(F f)
{
if constexpr (f(1UL)) {
return 1;
}
return 0;
}
int main()
{
auto predicate = [](auto v) constexpr -> bool // does not compile when v is auto and the return type is specified
{
return v == 1;
};
return func(predicate);
}
error
<source>:5:16: error: constexpr if condition is not a constant expression
5 | if constexpr (f(1UL)) {
| ^~~~~~
<source>:19:9: note: in instantiation of function template specialization 'func<(lambda at <source>:14:19)>' requested here
19 | return func(predicate);
| ^
<source>:5:16: note: undefined function 'operator()<unsigned long>' cannot be used in a constant expression
5 | if constexpr (f(1UL)) {
| ^
<source>:14:19: note: declared here
14 | auto predicate = [](auto v) constexpr -> bool // does not compile when v is auto and the return type is specified
| ^
1 error generated.
Compiler returned: 1
@llvm/issue-subscribers-clang-frontend
Author: None (llvmbot)
I wonder if this is related to: https://github.com/llvm/llvm-project/issues/71015
Reopen it as the PR has been reverted in https://github.com/llvm/llvm-project/pull/98991.
Extended Description
When constexpr lambda used in constant expression it going non constant when its parameter is auto.
In this sample got an error:
1> ConsoleApplication1.cpp(20,16): error : constexpr if condition is not a constant expression 1> if constexpr (f(TypeTag::value))
1> ^
~~~~~~~But if
auto predicate = [](auto v) constexpr -> bool
replaced by
auto predicate = [](size_t v) constexpr -> bool
all ok.
include
template
struct TypeTag
{
constexpr static size_t value = 1;
};
template<> struct TypeTag
{
constexpr static size_t value = 2;
};
template<typename T, typename F> constexpr auto func(F f) { if constexpr (f(TypeTag::value))
{
return int{1};
}
else
{
return float{2.2f};
}
}
int main() { auto predicate = [](auto v) constexpr -> bool // does not compile when v is auto { return v == 1; };
}