[clang] [Clang][NFCI] Initialize PredefinedNames immediately (PR #183295)
Steffen Larsen via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 2 04:55:02 PST 2026
https://github.com/steffenlarsen updated https://github.com/llvm/llvm-project/pull/183295
>From 56f31fb816df494234e25f44aa7a73ba61955d05 Mon Sep 17 00:00:00 2001
From: Steffen Holst Larsen <sholstla at amd.com>
Date: Wed, 25 Feb 2026 06:20:36 -0600
Subject: [PATCH] [Clang][NFCI] Initialize PredefinedNames immediately
In isPredefinedUnsafeLibcFunc the set of predefined names is initialized
lazily. However, this pattern is redundant as function-scope static
variables are initialized on first pass through the control flow. This
commit makes the variable constant, makes it a stack variable, and
initializes it immediately. This has the following benefits:
- The initialization pattern cleaner and potentially easier for the
compiler to optimize.
- Making the variable const avoid it being used as mutable global state.
- Having immediate initialization removes a potential race condition.
Signed-off-by: Steffen Holst Larsen <sholstla at amd.com>
---
clang/lib/Analysis/UnsafeBufferUsage.cpp | 147 +++++++++++------------
1 file changed, 72 insertions(+), 75 deletions(-)
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 193851cc5f381..133e39b8fac2b 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -1032,79 +1032,76 @@ hasUnsafeFormatOrSArg(ASTContext &Ctx, const CallExpr *Call,
// The notation `CoreName[str/wcs]` means a new name obtained from replace
// string "wcs" with "str" in `CoreName`.
static bool isPredefinedUnsafeLibcFunc(const FunctionDecl &Node) {
- static std::unique_ptr<std::set<StringRef>> PredefinedNames = nullptr;
- if (!PredefinedNames)
- PredefinedNames =
- std::make_unique<std::set<StringRef>, std::set<StringRef>>({
- // numeric conversion:
- "atof",
- "atoi",
- "atol",
- "atoll",
- "strtol",
- "strtoll",
- "strtoul",
- "strtoull",
- "strtof",
- "strtod",
- "strtold",
- "strtoimax",
- "strtoumax",
- // "strfromf", "strfromd", "strfroml", // C23?
- // string manipulation:
- "strcpy",
- "strncpy",
- "strlcpy",
- "strcat",
- "strncat",
- "strlcat",
- "strxfrm",
- "strdup",
- "strndup",
- // string examination:
- "strlen",
- "strnlen",
- "strcmp",
- "strncmp",
- "stricmp",
- "strcasecmp",
- "strcoll",
- "strchr",
- "strrchr",
- "strspn",
- "strcspn",
- "strpbrk",
- "strstr",
- "strtok",
- // "mem-" functions
- "memchr",
- "wmemchr",
- "memcmp",
- "wmemcmp",
- "memcpy",
- "memccpy",
- "mempcpy",
- "wmemcpy",
- "memmove",
- "wmemmove",
- "wmemset",
- // IO:
- "fread",
- "fwrite",
- "fgets",
- "fgetws",
- "gets",
- "fputs",
- "fputws",
- "puts",
- // others
- "strerror_s",
- "strerror_r",
- "bcopy",
- "bzero",
- "bsearch",
- "qsort",
- });
+ static const std::set<StringRef> PredefinedNames = {
+ // numeric conversion:
+ "atof",
+ "atoi",
+ "atol",
+ "atoll",
+ "strtol",
+ "strtoll",
+ "strtoul",
+ "strtoull",
+ "strtof",
+ "strtod",
+ "strtold",
+ "strtoimax",
+ "strtoumax",
+ // "strfromf", "strfromd", "strfroml", // C23?
+ // string manipulation:
+ "strcpy",
+ "strncpy",
+ "strlcpy",
+ "strcat",
+ "strncat",
+ "strlcat",
+ "strxfrm",
+ "strdup",
+ "strndup",
+ // string examination:
+ "strlen",
+ "strnlen",
+ "strcmp",
+ "strncmp",
+ "stricmp",
+ "strcasecmp",
+ "strcoll",
+ "strchr",
+ "strrchr",
+ "strspn",
+ "strcspn",
+ "strpbrk",
+ "strstr",
+ "strtok",
+ // "mem-" functions
+ "memchr",
+ "wmemchr",
+ "memcmp",
+ "wmemcmp",
+ "memcpy",
+ "memccpy",
+ "mempcpy",
+ "wmemcpy",
+ "memmove",
+ "wmemmove",
+ "wmemset",
+ // IO:
+ "fread",
+ "fwrite",
+ "fgets",
+ "fgetws",
+ "gets",
+ "fputs",
+ "fputws",
+ "puts",
+ // others
+ "strerror_s",
+ "strerror_r",
+ "bcopy",
+ "bzero",
+ "bsearch",
+ "qsort",
+ };
auto *II = Node.getIdentifier();
@@ -1114,7 +1111,7 @@ static bool isPredefinedUnsafeLibcFunc(const FunctionDecl &Node) {
StringRef Name = matchName(II->getName(), Node.getBuiltinID());
// Match predefined names:
- if (PredefinedNames->find(Name) != PredefinedNames->end())
+ if (PredefinedNames.count(Name))
return true;
std::string NameWCS = Name.str();
@@ -1126,7 +1123,7 @@ static bool isPredefinedUnsafeLibcFunc(const FunctionDecl &Node) {
NameWCS[WcsPos++] = 'r';
WcsPos = NameWCS.find("wcs", WcsPos);
}
- if (PredefinedNames->find(NameWCS) != PredefinedNames->end())
+ if (PredefinedNames.count(NameWCS))
return true;
// All `scanf` functions are unsafe (including `sscanf`, `vsscanf`, etc.. They
// all should end with "scanf"):
More information about the cfe-commits
mailing list