[clang-tidy] Warn on use of std::get_temporary_buffer (#176191)

The STL function `std::get_temporary_buffer` was originally designed
with the intent of providing a more efficient implementation than the
general-purpose operator new, but no such implementation was created and
the API was deprecated (in C++17) and removed (in C++20).

As this function is difficult to use and provides no advantages, I think
(or at least hope) that nobody actually uses it; but given that it was
present in the official standard, I think tidy should be able to report
its bugprone nature. (It returns uninitialized memory, which can cause
subtle bugs, e.g. as in the last code example of the SEI CERT rule
EXP54-CPP.)
This commit is contained in:
Donát Nagy 2026-01-19 17:56:24 +01:00 committed by GitHub
parent fc9feee1ef
commit 1219cc76d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 34 additions and 2 deletions

View File

@ -60,7 +60,8 @@ static StringRef getReplacementFor(StringRef FunctionName,
.Cases({"asctime", "asctime_r"}, "strftime")
.Case("gets", "fgets")
.Case("rewind", "fseek")
.Case("setbuf", "setvbuf");
.Case("setbuf", "setvbuf")
.Case("get_temporary_buffer", "operator new[]");
}
static StringRef getReplacementForAdditional(StringRef FunctionName,
@ -97,6 +98,9 @@ static StringRef getRationaleFor(StringRef FunctionName) {
.Cases({"rewind", "setbuf"}, "has no error detection")
.Case("vfork", "is insecure as it can lead to denial of service "
"situations in the parent process")
.Case("get_temporary_buffer", "returns uninitialized memory without "
"performance advantages, was deprecated in "
"C++17 and removed in C++20")
.Default("is not bounds-checking");
}
@ -221,7 +225,8 @@ void UnsafeFunctionsCheck::registerMatchers(MatchFinder *Finder) {
// Matching functions with replacements without Annex K.
auto FunctionNamesMatcher =
hasAnyName("::asctime", "asctime_r", "::gets", "::rewind", "::setbuf");
hasAnyName("::asctime", "asctime_r", "::gets", "::rewind", "::setbuf",
"::std::get_temporary_buffer");
Finder->addMatcher(
declRefExpr(
to(functionDecl(FunctionNamesMatcher).bind(FunctionNamesId)))

View File

@ -103,6 +103,11 @@ New check aliases
Changes in existing checks
^^^^^^^^^^^^^^^^^^^^^^^^^^
- Improved :doc:`bugprone-unsafe-functions
<clang-tidy/checks/bugprone/unsafe-functions>` check by adding the function
``std::get_temporary_buffer`` to the default list of unsafe functions. (This
function is unsafe, useless, deprecated in C++17 and removed in C++20).
- Improved :doc:`misc-const-correctness
<clang-tidy/checks/misc/const-correctness>` check:

View File

@ -48,6 +48,8 @@ availability:
- ``rewind``, suggested replacement: ``fseek``
- ``setbuf``, suggested replacement: ``setvbuf``
- ``std::get_temporary_buffer``, suggested replacement: "plain" allocation
with ``operator new[]``
If :option:`ReportMoreUnsafeFunctions` is enabled,
the following functions are also checked:

View File

@ -0,0 +1,20 @@
// RUN: %check_clang_tidy -std=c++11-or-later %s bugprone-unsafe-functions %t --
namespace std {
template <class T1, class T2>
struct pair {
T1 first;
T2 second;
};
using ptrdiff_t = long long;
template<class T>
std::pair<T*, std::ptrdiff_t>
get_temporary_buffer(std::ptrdiff_t count) noexcept;
}
void test() {
(void)std::get_temporary_buffer<int>(64);
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: function 'get_temporary_buffer<int>' returns uninitialized memory without performance advantages, was deprecated in C++17 and removed in C++20; 'operator new[]' should be used instead
}