[clang] [analyzer] Make recognition of hardened __FOO_chk functions explicit (PR #86536)

Balazs Benics via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 27 03:57:30 PDT 2024


================
@@ -110,13 +110,24 @@ bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD,
   if (FName.starts_with("__inline") && FName.contains(Name))
     return true;
 
-  if (FName.starts_with("__") && FName.ends_with("_chk") &&
-      FName.contains(Name))
-    return true;
-
   return false;
 }
 
+bool CheckerContext::isHardenedVariantOf(const FunctionDecl *FD,
+                                         StringRef Name) {
+  const IdentifierInfo *II = FD->getIdentifier();
+  if (!II)
+    return false;
+
+  StringRef FName = II->getName();
+  std::string ChkName = "__" + std::string(Name) + "_chk";
+
+  // This is using `equals()` instead of more lenient prefix/suffix/substring
+  // checks because we don't want to say that e.g. `__builtin___vsprintf_chk()`
+  // is a hardened variant of `sprintf()`.
+  return FName.equals(ChkName) || FName.equals("__builtin_" + ChkName);
+}
----------------
steakhal wrote:

```suggestion
bool CheckerContext::isHardenedVariantOf(const FunctionDecl *FD,
                                         StringRef Name) {
  const IdentifierInfo *II = FD->getIdentifier();
  if (!II)
    return false;

  auto CompletelyMatchesParts = [II](auto... Parts) -> bool {
    StringRef FName = II->getName();
    return (FName.consume_front(Parts) && ...) && FName.empty();
  };

  return CompletelyMatchesParts("__", Name, "_chk") ||
         CompletelyMatchesParts("__builtin_", "__", Name, "_chk");
}
```

I disliked the transient allocation, but here is my alternative achieving the same operating on StringRefs.

You had a comment about `__builtin___vsprintf_chk`. I wonder if we could have a test demonstrating that.

https://github.com/llvm/llvm-project/pull/86536


More information about the cfe-commits mailing list