Issue |
142267
|
Summary |
clang-tidy always emits clang-analyzer-core.CallAndMessage warning for reference captured structured bindings in lambdas
|
Labels |
clang-tidy
|
Assignees |
|
Reporter |
justusranvier
|
This is allowed by P1091R3 and implemented since #54300 however in every case I've found using these constructs clang-tidy emits uninitialized variable warnings.
code example:
```
#include <functional>
#include <list>
#include <map>
#include <string>
void maybe_consume(std::string const&, std::list<std::string>&);
void example()
{
auto var = std::map<std::string, std::list<std::string>>{};
for (auto i = var.begin(); i != var.end();) {
auto& [key, value] = *i;
auto p1091r3 = [&] { maybe_consume(key, value); };
std::invoke(p1091r3);
if (value.empty()) {
i = var.erase(i);
} else {
++i;
}
}
}
```
compiler output: https://godbolt.org/z/ns7Yc7GT8
clang-tidy command line: `clang-tidy --checks="clang-analyzer-*" --extra-arg="-std=c++20"`
clang-tidy output:
```
1 warning generated.
/home/user/src/examples/clang-analyzer-p1091r3.cpp:14:30: warning: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
14 | auto p1091r3 = [&] { maybe_consume(key, value); };
| ^
/home/user/src/examples/clang-analyzer-p1091r3.cpp:12:5: note: Loop condition is true. Entering loop body
12 | for (auto i = var.begin(); i != var.end();) {
| ^
/home/user/src/examples/clang-analyzer-p1091r3.cpp:15:9: note: Calling 'invoke<(lambda at /home/user/src/examples/clang-analyzer-p1091r3.cpp:14:24) &, >'
15 | std::invoke(p1091r3);
| ^~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/powerpc64le-unknown-linux-gnu/15/include/g++-v15/functional:122:14: note: Calling '__invoke<(lambda at /home/user/src/examples/clang-analyzer-p1091r3.cpp:14:24) &, >'
122 | return std::__invoke(std::forward<_Callable>(__fn),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123 | std::forward<_Args>(__args)...);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/powerpc64le-unknown-linux-gnu/15/include/g++-v15/bits/invoke.h:98:14: note: Calling '__invoke_impl<void, (lambda at /home/user/src/examples/clang-analyzer-p1091r3.cpp:14:24) &, >'
98 | return std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99 | std::forward<_Args>(__args)...);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/powerpc64le-unknown-linux-gnu/15/include/g++-v15/bits/invoke.h:63:14: note: Calling 'operator()'
63 | { return std::forward<_Fn>(__f)(std::forward<_Args>(__args)...); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/user/src/examples/clang-analyzer-p1091r3.cpp:14:30: note: 1st function call argument is an uninitialized value
14 | auto p1091r3 = [&] { maybe_consume(key, value); };
| ^ ~~~
```
Switching from default capture to named capture does not help:
```
1 warning generated.
/home/user/src/examples/clang-analyzer-p1091r3.cpp:14:41: warning: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
14 | auto p1091r3 = [&key, &value] { maybe_consume(key, value); };
| ^
/home/user/src/examples/clang-analyzer-p1091r3.cpp:12:5: note: Loop condition is true. Entering loop body
12 | for (auto i = var.begin(); i != var.end();) {
| ^
/home/user/src/examples/clang-analyzer-p1091r3.cpp:15:9: note: Calling 'invoke<(lambda at /home/user/src/examples/clang-analyzer-p1091r3.cpp:14:24) &, >'
15 | std::invoke(p1091r3);
| ^~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/powerpc64le-unknown-linux-gnu/15/include/g++-v15/functional:122:14: note: Calling '__invoke<(lambda at /home/user/src/examples/clang-analyzer-p1091r3.cpp:14:24) &, >'
122 | return std::__invoke(std::forward<_Callable>(__fn),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123 | std::forward<_Args>(__args)...);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/powerpc64le-unknown-linux-gnu/15/include/g++-v15/bits/invoke.h:98:14: note: Calling '__invoke_impl<void, (lambda at /home/user/src/examples/clang-analyzer-p1091r3.cpp:14:24) &, >'
98 | return std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99 | std::forward<_Args>(__args)...);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/powerpc64le-unknown-linux-gnu/15/include/g++-v15/bits/invoke.h:63:14: note: Calling 'operator()'
63 | { return std::forward<_Fn>(__f)(std::forward<_Args>(__args)...); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/user/src/examples/clang-analyzer-p1091r3.cpp:14:41: note: 1st function call argument is an uninitialized value
14 | auto p1091r3 = [&key, &value] { maybe_consume(key, value); };
| ^ ~~~
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs