Skip to content

Clang rejects referencing local variable of class type to initialize template parameter in body of function template #49927

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

Closed
davidstone opened this issue Jun 4, 2021 · 10 comments
Labels
bugzilla Issues migrated from bugzilla c++ clang:frontend Language frontend issues, e.g. anything involving "Sema" constexpr Anything related to constant evaluation lambda C++11 lambda expressions

Comments

@davidstone
Copy link
Contributor

Bugzilla Link 50583
Version trunk
OS Linux
CC @DougGregor,@zygoloid

Extended Description

The following well-formed translation unit

struct integral_constant {
	static constexpr auto value = 0;
};

template<int>
struct s {};

template<typename>
void function_template() {
	[] {
		constexpr auto x = integral_constant();
		s<x.value>();
	};
}

void f() {
	function_template<void>();
}

is rejected by clang with the error message

<source>:12:5: error: variable 'x' cannot be implicitly captured in a lambda with no capture-default specified
                s<x.value>();
                  ^
<source>:17:2: note: in instantiation of function template specialization 'function_template<void>' requested here
        function_template<void>();
        ^
<source>:11:18: note: 'x' declared here
                constexpr auto x = integral_constant();
                               ^
<source>:10:2: note: lambda expression begins here
        [] {
        ^
<source>:10:3: note: capture 'x' by value
        [] {
         ^
         x
<source>:10:3: note: capture 'x' by reference
        [] {
         ^
         &x
<source>:10:3: note: default capture by value
        [] {
         ^
         =
<source>:10:3: note: default capture by reference
        [] {
         ^
         &
1 error generated.
Compiler returned: 1

See it live: https://godbolt.org/z/a5Mjh8ojv

A very similar translation unit,

struct integral_constant {
};

template<auto>
struct s {};

template<typename>
void function_template() {
	[] {
		constexpr auto x = integral_constant();
		s<x>();
	};
}

void f() {
	function_template<void>();
}

is rejected for the same bogus reason.

@davidstone
Copy link
Contributor Author

Reduced test case -- the lambda is unnecessary

struct integral_constant {
	static constexpr auto value = 0;
};

template<int>
struct s {};

template<typename>
void function_template() {
	constexpr auto x = integral_constant();
	s<x.value>();
}

void f() {
	function_template<void>();
}

Rejected with

<source>:11:4: error: reference to local variable 'x' declared in enclosing function 'function_template'
        s<x.value>();
          ^
<source>:15:2: note: in instantiation of function template specialization 'function_template<void>' requested here
        function_template<void>();
        ^
<source>:10:17: note: 'x' declared here
        constexpr auto x = integral_constant();
                       ^
1 error generated.
Compiler returned: 1

See it live: https://godbolt.org/z/Yaes1h6M5

@davidstone
Copy link
Contributor Author

A workaround is to declare the variable static.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 11, 2021
@JohelEGP
Copy link

The same happens when you invoke a lambda during constant evaluation, see #61029.

@EugeneZelenko EugeneZelenko added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Feb 27, 2023
@llvmbot
Copy link
Member

llvmbot commented Feb 27, 2023

@llvm/issue-subscribers-clang-frontend

@ldalessa
Copy link

ldalessa commented Aug 30, 2024

Ran into this today with

void foo()
{
    constexpr int x{1};
    using A = decltype([]<int=x>{});
}

Would be great to see this fixed.

@zyn0217
Copy link
Contributor

zyn0217 commented Sep 3, 2024

The original issue seems to have been fixed since around Clang 15.

https://godbolt.org/z/rKzKGs54z

@zyn0217 zyn0217 added lambda C++11 lambda expressions constexpr Anything related to constant evaluation labels Sep 3, 2024
@ldalessa
Copy link

ldalessa commented Sep 3, 2024

The original issue seems to have been fixed since around Clang 15.

https://godbolt.org/z/rKzKGs54z

Oh weird. My issue seems new in clang-17.

https://godbolt.org/z/5T358neaY

Would it make more sense to create a new issue for this (or are you familiar with one that's active?).

@zyn0217
Copy link
Contributor

zyn0217 commented Sep 3, 2024

Yeah, I think that merits a new issue.
(My intuition is that this might be a regression caused by https://reviews.llvm.org/D124351, but I'm not sure before running a debugger.)

@ldalessa
Copy link

ldalessa commented Sep 3, 2024

Submitted as #107048.

@zyn0217
Copy link
Contributor

zyn0217 commented Sep 4, 2024

I'm closing this one - the case doesn't reproduce anyway.

@zyn0217 zyn0217 closed this as completed Sep 4, 2024
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++ 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

6 participants