-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[clang-tidy] std::addressof
not checked by clang-analyzer-core.StackAddressEscape
#94193
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
Comments
@llvm/issue-subscribers-clang-static-analyzer Author: None (dfrvfmst)
The code examples are all in C++23 (`-std=c++23`) and libc++ (`-stdlib=libc++ -fexperimental-library`).
Given a basic example: #include <iostream>
#include <memory>
#include <string>
auto f1()
{
std::string a = "123";
return std::addressof(a);
}
int main()
{
auto result = f1();
std::cout << *result;
} It isn't caught by
This is weird, given the fact that Definition of template <class _Tp>
inline _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_NO_CFI _LIBCPP_HIDE_FROM_ABI _Tp* addressof(_Tp& __x) _NOEXCEPT {
return __builtin_addressof(__x);
} When changing the example to use auto f1()
{
std::string a = "123";
return __builtin_addressof(a);
}
This issue might be what caused Example of faulty code utilizing #include <iostream>
#include <ranges>
#include <vector>
auto f2()
{
std::vector a{1, 2, 3};
return a | std::ranges::views::filter([](auto &&_) { return _ > 1; });
}
int main()
{
auto result = f2();
for (auto &&e : result) {
std::cout << e;
}
}
Example of faulty code utilizing #include <iostream>
#include <functional>
#include <string>
auto f3()
{
std::string a = "123";
return std::ref(a);
}
int main()
{
auto result = f3();
std::cout << result.get();
}
More interestingly, if you implement your own reference wrapper that works similar to the one in libc++ by storing address, Definition of template<typename T>
struct Ref
{
Ref(T &ref)
: ptr(&ref)
{}
auto &get(this auto &&self) { return *self.ptr; }
private:
T *ptr;
}; Faulty code utilizing #include <iostream>
#include <string>
auto f4()
{
std::string a = "123";
return Ref{a};
}
int main()
{
auto result = f4();
std::cout << result.get();
}
But, when you change the constructor of Version:
|
Thanks for the detailed report. |
A somewhat relevant example that uses string_view: https://godbolt.org/z/8d5r5nMbG If you replace the |
Is this a good first issue? What kind of skills are required to diagnose and patch it? |
Some template function instantiations don't have a body, even though their templates did have a body. Examples are: `std::move`, `std::forward`, `std::addressof` etc. They had bodies before 72315d0 After that change, the sentiment was that these special functions should be considered and treated as builtin functions. Fixes #94193 CPP-5358
Summary: Some template function instantiations don't have a body, even though their templates did have a body. Examples are: `std::move`, `std::forward`, `std::addressof` etc. They had bodies before 72315d0 After that change, the sentiment was that these special functions should be considered and treated as builtin functions. Fixes #94193 CPP-5358 Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251093
The code examples are all in C++23 (
-std=c++23
) and libc++ (-stdlib=libc++ -fexperimental-library
).Given a basic example:
It isn't caught by
clang-tidy
, and instead ASan catches it in runtime:This is weird, given the fact that
__builtin_addressof
is checked byclang-tidy
and (at least inlibc++
)std::addressof
is simply a wrapper that calls__builtin_addressof
.Definition of
std::addressof
:When changing the example to use
__builtin_addressof
:clang-tidy
is able to figure out that it's returning a dangling pointer:This issue might be what caused
std::reference_wrapper
andstd::ranges::ref_view
to be unchecked, since (in libc++) they also usedstd::addressof
in their constructors.Example of faulty code utilizing
std::ranges::ref_view
:clang-tidy
doesn't catch it. ASan catches it (stack-use-after-return
).Example of faulty code utilizing
std::reference_wrapper
:clang-tidy
doesn't catch it. ASan catches it (stack-use-after-return
).More interestingly, if you implement your own reference wrapper that works similar to the one in libc++ by storing address,
clang-tidy
can detect the returning of dangling pointer/reference as long asstd::addressof
isn't used in constructor.Definition of
Ref
:Faulty code utilizing
Ref
:clang-tidy
catches it:But, when you change the constructor of
Ref
to usestd::addressof(ref)
,clang-tidy
can no longer detect it, which leads to me thinking the case withstd::reference_wrapper
andstd::ranges::ref_view
.Version:
The text was updated successfully, but these errors were encountered: