You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
int main()
{
S s{42};
auto& [x] = s;
auto g = x{ f(x); };
g();
}
This is perfectly valid C++20 code AFAIK, and compiles with both gcc (13) and clang (18.1).
The static analyzer, however, gets upset:
$ clang++ --version
clang version 18.1.5
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/lib/llvm/18/bin
Configuration file: /etc/clang/x86_64-pc-linux-gnu-clang++.cfg
$ clang++ --analyze --analyzer-output text bindings.cpp
bindings.cpp:9:23: warning: Dereference of undefined pointer value [core.NullDereference]
9 | auto g = x{ f(x); };
| ^
bindings.cpp:10:5: note: Calling 'operator()'
10 | g();
| ^~~
bindings.cpp:9:23: note: Dereference of undefined pointer value
9 | auto g = x{ f(x); };
| ^
1 warning generated.
But `x` in that context is neither a pointer nor undefined, as it's being captured by value into the lambda.
Godbolt to reproduce: https://godbolt.org/z/3zha6nv5f
Perhaps noteworthy:
- The same warning is emitted if `x` is captured by reference, i.e. `[&x]`
- The same warning is emitted if default by-value `[=]` or by-reference `[&]` capture is used
- However, if `x` is captured explicitly using an initializer (`[x = x]` or `[&x = x]`) the warning is not emitted
</details>
Thanks for reporting it. Your report is extensive and minimal, thanks for that!
The issue is that from the lambda body, we try to load form variable x from ExprEngine::VisitCommonDeclRefExpr, where D is a BindingDecl, which refers to a DecompositionDecl with reference type. Then the Base = state->getSVal(R) will associate undefinedVal with Base.
Instead, Base should refer to the address of the lambda itself, so that the binding in the store (temp_object{class (lambda at code.cpp:9:12), S1144}: 42 S32b) would be loaded instead.
Reproducible example:
This is perfectly valid C++20 code AFAIK, and compiles with both GCC (13) and Clang (18.1).
The static analyzer, however, gets upset:
But
x
in that context is neither a pointer nor undefined, as it's being captured by value into the lambda.Godbolt to reproduce: https://godbolt.org/z/3zha6nv5f
Perhaps noteworthy:
x
is captured by reference, i.e.[&x]
[=]
or by-reference[&]
capture is usedx
is captured explicitly using an initializer ([x = x]
or[&x = x]
) the warning is not emittedThe text was updated successfully, but these errors were encountered: