Skip to content

[clang++] constexpr is not propagated in lambda in a template context under specific condition #94849

Closed as not planned
@stephen-hqxu

Description

@stephen-hqxu

I initially discovered this issue on the official clang 18 build on Ubuntu. Then I did a quick test on compiler explorer, and it seems to affect all clang versions (starting clang 5) that support C++17 constexpr lambda feature; perhaps platform does not really matter.

Consider the following code:

template<typename = void>
void doStuff() {
	auto equalsOne = [](auto x) -> bool {
		return x == 1;
	};
	static_assert(equalsOne(1), "oops");
}

int main() {
	doStuff();
}

And compile with:

clang++ -std=c++17 ./example.cpp -o example

This code does not compile and will generate the following errors:

static assertion expression is not an integral constant expression
static_assert(equalsOne(1), "oops");

There are a few observations:

  • The code compiles on GCC and MSVC.
  • Make doStuff non-template, i.e. removing template<typename = void>, compiles.
  • Change the lambda call signature from auto x to int x, compiles. However, it still does not compile if it is in C++20 and replace auto with explicit lambda template parameter. This basically means it does not compile when lambda is a template, regardless of how it is templated.
  • Change the trailing return type of lambda -> bool to -> auto, or equivalently removing the trailing return type, compiles.
  • It does not compile even if decorating the lambda with constexpr, i.e. [](auto x) constexpr -> bool.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"constexprAnything related to constant evaluationduplicateResolved as duplicatelambdaC++11 lambda expressions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions