Skip to content
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

Clang: immediately-invoked lambda in template arg is not implicitly constexpr #114234

Open
elbeno opened this issue Oct 30, 2024 · 3 comments
Open
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" constexpr Anything related to constant evaluation lambda C++11 lambda expressions

Comments

@elbeno
Copy link

elbeno commented Oct 30, 2024

An IILE as a template argument inside some other templates; this is the smallest SSCCE I could find.

template <auto Arg>
auto g() { return Arg; }

template <typename>
auto f() {
    []<typename>() {
        // lambda is not treated as implicitly constexpr?
        g<[] { return 123; }()>();
        // explicit constexpr works
        // g<[] () constexpr { return 123; }()>();
    }.template operator()<int>();
}

int main() { f<int>(); }

produces:

<source>:8:9: error: no matching function for call to 'g'
    8 |         g<[] { return 123; }()>();
      |         ^~~~~~~~~~~~~~~~~~~~~~~
<source>:6:20: note: while substituting into a lambda expression here
    6 |     []<typename>() {
      |                    ^
<source>:14:14: note: in instantiation of function template specialization 'f<int>' requested here
   14 | int main() { f<int>(); }
      |              ^
<source>:2:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Arg'
    2 | auto g() { return Arg; }
      |      ^
1 error generated.

https://godbolt.org/z/x6heGf38x

@github-actions github-actions bot added the clang Clang issues not falling into any other category label Oct 30, 2024
elbeno added a commit to elbeno/cpp-std-extensions that referenced this issue Oct 30, 2024
Problem:
- Writing `STATIC_ASSERT(cond, str)` means that `str` has to be formatted either
  as a separate variable or inline in the call.

Solution:
- Allow `STATIC_ASSERT(cond, fmt_str, args...)` where the string is formatted
  automatically.

Notes:
- Each argument must still be wrapped in `CX_VALUE`. Because there is no
  generic equivalent of `transform` for `__VA_ARGS__`.
- A bug in clang (for which a workaround is in place) was discovered:
  llvm/llvm-project#114234
- `CX_VALUE` has been made more workable with GCC. GCC did not allow the
  `struct` definition inside the macro.
@tbaederr
Copy link
Contributor

Yup, the operator() of the lambda is not constexpr:

CXXMethodDecl 0x7e0f6b6bf760 <./array.cpp:124:12, col:28> col:11 referenced operator() 'auto () const -> int' implicit_instantiation inline instantiated_from 0x7e0f6b6bc900
`-CompoundStmt 0x7e0f6b6bfa30 <col:14, col:28>
  `-ReturnStmt 0x7e0f6b6bfa18 <col:16, col:23>
    `-IntegerLiteral 0x7e0f6b6bcab8 <col:23> 'int' 123

@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" lambda C++11 lambda expressions constexpr Anything related to constant evaluation and removed clang Clang issues not falling into any other category labels Oct 30, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 30, 2024

@llvm/issue-subscribers-clang-frontend

Author: Ben Deane (elbeno)

An IILE as a template argument inside some other templates; this is the smallest SSCCE I could find.
template &lt;auto Arg&gt;
auto g() { return Arg; }

template &lt;typename&gt;
auto f() {
    []&lt;typename&gt;() {
        // lambda is not treated as implicitly constexpr?
        g&lt;[] { return 123; }()&gt;();
        // explicit constexpr works
        // g&lt;[] () constexpr { return 123; }()&gt;();
    }.template operator()&lt;int&gt;();
}

int main() { f&lt;int&gt;(); }

produces:

&lt;source&gt;:8:9: error: no matching function for call to 'g'
    8 |         g&lt;[] { return 123; }()&gt;();
      |         ^~~~~~~~~~~~~~~~~~~~~~~
&lt;source&gt;:6:20: note: while substituting into a lambda expression here
    6 |     []&lt;typename&gt;() {
      |                    ^
&lt;source&gt;:14:14: note: in instantiation of function template specialization 'f&lt;int&gt;' requested here
   14 | int main() { f&lt;int&gt;(); }
      |              ^
&lt;source&gt;:2:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Arg'
    2 | auto g() { return Arg; }
      |      ^
1 error generated.

https://godbolt.org/z/x6heGf38x

@zyn0217
Copy link
Contributor

zyn0217 commented Nov 25, 2024

Maybe related #97958

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

No branches or pull requests

5 participants