Skip to content

lambda expression is not a constant expression when auto (generic) parameter is used. #35052

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

Open
llvmbot opened this issue Dec 20, 2017 · 4 comments · Fixed by #95660
Open
Labels
bugzilla Issues migrated from bugzilla c++17 clang:frontend Language frontend issues, e.g. anything involving "Sema" constexpr Anything related to constant evaluation lambda C++11 lambda expressions rejects-valid

Comments

@llvmbot
Copy link
Member

llvmbot commented Dec 20, 2017

Bugzilla Link 35704
Version trunk
OS Windows NT
Attachments sample cpp file
Reporter LLVM Bugzilla Contributor

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;
};

constexpr auto ok = predicate(75);

constexpr auto fail = func<int>(predicate);

return 0;

}

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
@wheatman
Copy link
Contributor

wheatman commented Nov 7, 2023

This is still being rejected with post 17 trunk(cf7d4f5)
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

@wheatman wheatman added clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid labels Nov 7, 2023
@llvmbot
Copy link
Member Author

llvmbot commented Nov 7, 2023

@llvm/issue-subscribers-clang-frontend

Author: None (llvmbot)

| | | | --- | --- | | Bugzilla Link | [35704](https://llvm.org/bz35704) | | Version | trunk | | OS | Windows NT | | Attachments | [sample cpp file](https://user-images.githubusercontent.com/60944935/143756747-1ebddae5-0c33-4886-ae99-12a8f1d0fed6.gz) | | Reporter | LLVM Bugzilla Contributor |

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<T>::value))
1> ^~~~~~~~~~~~~~~~~~~~

But if

auto predicate = [](auto v) constexpr -> bool

replaced by

auto predicate = [](size_t v) constexpr -> bool

all ok.


#include <iostream>

template<typename T>
struct TypeTag
{
constexpr static size_t value = 1;
};

template<>
struct TypeTag<float>
{
constexpr static size_t value = 2;
};

template<typename T, typename F>
constexpr auto func(F f)
{
if constexpr (f(TypeTag<T>::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;
};

constexpr auto ok = predicate(75);

constexpr auto fail = func&lt;int&gt;(predicate);

return 0;

}

@shafik
Copy link
Collaborator

shafik commented Dec 2, 2023

I wonder if this is related to: #71015

@zyn0217
Copy link
Contributor

zyn0217 commented Jul 16, 2024

Reopen it as the PR has been reverted in #98991.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c++17 clang:frontend Language frontend issues, e.g. anything involving "Sema" constexpr Anything related to constant evaluation lambda C++11 lambda expressions rejects-valid
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants