Skip to content
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

[analyzer] Use CDM::CLibrary instead of isGlobalCFunction() #88267

Merged

Conversation

NagyDonat
Copy link
Contributor

This commit updates several checkers to use call descriptions with the matching mode CDM::CLibrary instead checking Call.isGlobalCFunction() after performing the match. This resolves several TODOs in various checkers.

Note that both matching with CDM::CLibrary and calling isGlobalCFunction leads to CheckerContext::isCLibraryFunction() checks (so this change is close to being NFC), but if it is used via the matching mode then the checker can automatically recognize the builtin variants of the matched functions.

I'll also make similar changes in GenericTaintChecker, but that checker has separate and inconsistent rules for handling the normal and the builtin variant of several functions (e.g. memcpy and __builtin_memcpy), so I'll put those changes into a separate commit.

This commit updates several checkers to use call descriptions with the
matching mode `CDM::CLibrary` instead checking `Call.isGlobalCFunction()`
after performing the match. This resolves several TODOs in various
checkers.

Note that both matching with `CDM::CLibrary` and calling
`isGlobalCFunction` leads to `CheckerContext::isCLibraryFunction()`
checks (so this change is close to being NFC), but if it is used via the
matching mode then the checker can automatically recognize the builtin
variants of the matched functions.

I'll also make similar changes in GenericTaintChecker, but that checker
has separate and inconsistent rules for handling the normal and the
builtin variant of several functions (e.g. `memcpy` and
`__builtin_memcpy`), so I'll put those changes into a separate commit.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:static analyzer labels Apr 10, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Apr 10, 2024

@llvm/pr-subscribers-clang-static-analyzer-1

@llvm/pr-subscribers-clang

Author: None (NagyDonat)

Changes

This commit updates several checkers to use call descriptions with the matching mode CDM::CLibrary instead checking Call.isGlobalCFunction() after performing the match. This resolves several TODOs in various checkers.

Note that both matching with CDM::CLibrary and calling isGlobalCFunction leads to CheckerContext::isCLibraryFunction() checks (so this change is close to being NFC), but if it is used via the matching mode then the checker can automatically recognize the builtin variants of the matched functions.

I'll also make similar changes in GenericTaintChecker, but that checker has separate and inconsistent rules for handling the normal and the builtin variant of several functions (e.g. memcpy and __builtin_memcpy), so I'll put those changes into a separate commit.


Patch is 20.19 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/88267.diff

5 Files Affected:

  • (modified) clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp (+4-8)
  • (modified) clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp (+72-43)
  • (modified) clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp (+2-8)
  • (modified) clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp (+35-34)
  • (modified) clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp (+17-18)
diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index c72a97cc01e914..80f128b917b200 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -542,10 +542,10 @@ namespace {
 class CFRetainReleaseChecker : public Checker<check::PreCall> {
   mutable APIMisuse BT{this, "null passed to CF memory management function"};
   const CallDescriptionSet ModelledCalls = {
-      {{"CFRetain"}, 1},
-      {{"CFRelease"}, 1},
-      {{"CFMakeCollectable"}, 1},
-      {{"CFAutorelease"}, 1},
+      {CDM::CLibrary, {"CFRetain"}, 1},
+      {CDM::CLibrary, {"CFRelease"}, 1},
+      {CDM::CLibrary, {"CFMakeCollectable"}, 1},
+      {CDM::CLibrary, {"CFAutorelease"}, 1},
   };
 
 public:
@@ -555,10 +555,6 @@ class CFRetainReleaseChecker : public Checker<check::PreCall> {
 
 void CFRetainReleaseChecker::checkPreCall(const CallEvent &Call,
                                           CheckerContext &C) const {
-  // TODO: Make this check part of CallDescription.
-  if (!Call.isGlobalCFunction())
-    return;
-
   // Check if we called CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
   if (!ModelledCalls.contains(Call))
     return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
index fa8572cf85edfe..86530086ff1b27 100644
--- a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
@@ -87,7 +87,8 @@ class PthreadLockChecker : public Checker<check::PostCall, check::DeadSymbols,
                                               CheckerKind CheckKind) const;
   CallDescriptionMap<FnCheck> PThreadCallbacks = {
       // Init.
-      {{{"pthread_mutex_init"}, 2}, &PthreadLockChecker::InitAnyLock},
+      {{CDM::CLibrary, {"pthread_mutex_init"}, 2},
+       &PthreadLockChecker::InitAnyLock},
       // TODO: pthread_rwlock_init(2 arguments).
       // TODO: lck_mtx_init(3 arguments).
       // TODO: lck_mtx_alloc_init(2 arguments) => returns the mutex.
@@ -95,74 +96,106 @@ class PthreadLockChecker : public Checker<check::PostCall, check::DeadSymbols,
       // TODO: lck_rw_alloc_init(2 arguments) => returns the mutex.
 
       // Acquire.
-      {{{"pthread_mutex_lock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},
-      {{{"pthread_rwlock_rdlock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},
-      {{{"pthread_rwlock_wrlock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},
-      {{{"lck_mtx_lock"}, 1}, &PthreadLockChecker::AcquireXNULock},
-      {{{"lck_rw_lock_exclusive"}, 1}, &PthreadLockChecker::AcquireXNULock},
-      {{{"lck_rw_lock_shared"}, 1}, &PthreadLockChecker::AcquireXNULock},
+      {{CDM::CLibrary, {"pthread_mutex_lock"}, 1},
+       &PthreadLockChecker::AcquirePthreadLock},
+      {{CDM::CLibrary, {"pthread_rwlock_rdlock"}, 1},
+       &PthreadLockChecker::AcquirePthreadLock},
+      {{CDM::CLibrary, {"pthread_rwlock_wrlock"}, 1},
+       &PthreadLockChecker::AcquirePthreadLock},
+      {{CDM::CLibrary, {"lck_mtx_lock"}, 1},
+       &PthreadLockChecker::AcquireXNULock},
+      {{CDM::CLibrary, {"lck_rw_lock_exclusive"}, 1},
+       &PthreadLockChecker::AcquireXNULock},
+      {{CDM::CLibrary, {"lck_rw_lock_shared"}, 1},
+       &PthreadLockChecker::AcquireXNULock},
 
       // Try.
-      {{{"pthread_mutex_trylock"}, 1}, &PthreadLockChecker::TryPthreadLock},
-      {{{"pthread_rwlock_tryrdlock"}, 1}, &PthreadLockChecker::TryPthreadLock},
-      {{{"pthread_rwlock_trywrlock"}, 1}, &PthreadLockChecker::TryPthreadLock},
-      {{{"lck_mtx_try_lock"}, 1}, &PthreadLockChecker::TryXNULock},
-      {{{"lck_rw_try_lock_exclusive"}, 1}, &PthreadLockChecker::TryXNULock},
-      {{{"lck_rw_try_lock_shared"}, 1}, &PthreadLockChecker::TryXNULock},
+      {{CDM::CLibrary, {"pthread_mutex_trylock"}, 1},
+       &PthreadLockChecker::TryPthreadLock},
+      {{CDM::CLibrary, {"pthread_rwlock_tryrdlock"}, 1},
+       &PthreadLockChecker::TryPthreadLock},
+      {{CDM::CLibrary, {"pthread_rwlock_trywrlock"}, 1},
+       &PthreadLockChecker::TryPthreadLock},
+      {{CDM::CLibrary, {"lck_mtx_try_lock"}, 1},
+       &PthreadLockChecker::TryXNULock},
+      {{CDM::CLibrary, {"lck_rw_try_lock_exclusive"}, 1},
+       &PthreadLockChecker::TryXNULock},
+      {{CDM::CLibrary, {"lck_rw_try_lock_shared"}, 1},
+       &PthreadLockChecker::TryXNULock},
 
       // Release.
-      {{{"pthread_mutex_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},
-      {{{"pthread_rwlock_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},
-      {{{"lck_mtx_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},
-      {{{"lck_rw_unlock_exclusive"}, 1}, &PthreadLockChecker::ReleaseAnyLock},
-      {{{"lck_rw_unlock_shared"}, 1}, &PthreadLockChecker::ReleaseAnyLock},
-      {{{"lck_rw_done"}, 1}, &PthreadLockChecker::ReleaseAnyLock},
+      {{CDM::CLibrary, {"pthread_mutex_unlock"}, 1},
+       &PthreadLockChecker::ReleaseAnyLock},
+      {{CDM::CLibrary, {"pthread_rwlock_unlock"}, 1},
+       &PthreadLockChecker::ReleaseAnyLock},
+      {{CDM::CLibrary, {"lck_mtx_unlock"}, 1},
+       &PthreadLockChecker::ReleaseAnyLock},
+      {{CDM::CLibrary, {"lck_rw_unlock_exclusive"}, 1},
+       &PthreadLockChecker::ReleaseAnyLock},
+      {{CDM::CLibrary, {"lck_rw_unlock_shared"}, 1},
+       &PthreadLockChecker::ReleaseAnyLock},
+      {{CDM::CLibrary, {"lck_rw_done"}, 1},
+       &PthreadLockChecker::ReleaseAnyLock},
 
       // Destroy.
-      {{{"pthread_mutex_destroy"}, 1}, &PthreadLockChecker::DestroyPthreadLock},
-      {{{"lck_mtx_destroy"}, 2}, &PthreadLockChecker::DestroyXNULock},
+      {{CDM::CLibrary, {"pthread_mutex_destroy"}, 1},
+       &PthreadLockChecker::DestroyPthreadLock},
+      {{CDM::CLibrary, {"lck_mtx_destroy"}, 2},
+       &PthreadLockChecker::DestroyXNULock},
       // TODO: pthread_rwlock_destroy(1 argument).
       // TODO: lck_rw_destroy(2 arguments).
   };
 
   CallDescriptionMap<FnCheck> FuchsiaCallbacks = {
       // Init.
-      {{{"spin_lock_init"}, 1}, &PthreadLockChecker::InitAnyLock},
+      {{CDM::CLibrary, {"spin_lock_init"}, 1},
+       &PthreadLockChecker::InitAnyLock},
 
       // Acquire.
-      {{{"spin_lock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},
-      {{{"spin_lock_save"}, 3}, &PthreadLockChecker::AcquirePthreadLock},
-      {{{"sync_mutex_lock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},
-      {{{"sync_mutex_lock_with_waiter"}, 1},
+      {{CDM::CLibrary, {"spin_lock"}, 1},
+       &PthreadLockChecker::AcquirePthreadLock},
+      {{CDM::CLibrary, {"spin_lock_save"}, 3},
+       &PthreadLockChecker::AcquirePthreadLock},
+      {{CDM::CLibrary, {"sync_mutex_lock"}, 1},
+       &PthreadLockChecker::AcquirePthreadLock},
+      {{CDM::CLibrary, {"sync_mutex_lock_with_waiter"}, 1},
        &PthreadLockChecker::AcquirePthreadLock},
 
       // Try.
-      {{{"spin_trylock"}, 1}, &PthreadLockChecker::TryFuchsiaLock},
-      {{{"sync_mutex_trylock"}, 1}, &PthreadLockChecker::TryFuchsiaLock},
-      {{{"sync_mutex_timedlock"}, 2}, &PthreadLockChecker::TryFuchsiaLock},
+      {{CDM::CLibrary, {"spin_trylock"}, 1},
+       &PthreadLockChecker::TryFuchsiaLock},
+      {{CDM::CLibrary, {"sync_mutex_trylock"}, 1},
+       &PthreadLockChecker::TryFuchsiaLock},
+      {{CDM::CLibrary, {"sync_mutex_timedlock"}, 2},
+       &PthreadLockChecker::TryFuchsiaLock},
 
       // Release.
-      {{{"spin_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},
-      {{{"spin_unlock_restore"}, 3}, &PthreadLockChecker::ReleaseAnyLock},
-      {{{"sync_mutex_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},
+      {{CDM::CLibrary, {"spin_unlock"}, 1},
+       &PthreadLockChecker::ReleaseAnyLock},
+      {{CDM::CLibrary, {"spin_unlock_restore"}, 3},
+       &PthreadLockChecker::ReleaseAnyLock},
+      {{CDM::CLibrary, {"sync_mutex_unlock"}, 1},
+       &PthreadLockChecker::ReleaseAnyLock},
   };
 
   CallDescriptionMap<FnCheck> C11Callbacks = {
       // Init.
-      {{{"mtx_init"}, 2}, &PthreadLockChecker::InitAnyLock},
+      {{CDM::CLibrary, {"mtx_init"}, 2}, &PthreadLockChecker::InitAnyLock},
 
       // Acquire.
-      {{{"mtx_lock"}, 1}, &PthreadLockChecker::AcquirePthreadLock},
+      {{CDM::CLibrary, {"mtx_lock"}, 1},
+       &PthreadLockChecker::AcquirePthreadLock},
 
       // Try.
-      {{{"mtx_trylock"}, 1}, &PthreadLockChecker::TryC11Lock},
-      {{{"mtx_timedlock"}, 2}, &PthreadLockChecker::TryC11Lock},
+      {{CDM::CLibrary, {"mtx_trylock"}, 1}, &PthreadLockChecker::TryC11Lock},
+      {{CDM::CLibrary, {"mtx_timedlock"}, 2}, &PthreadLockChecker::TryC11Lock},
 
       // Release.
-      {{{"mtx_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},
+      {{CDM::CLibrary, {"mtx_unlock"}, 1}, &PthreadLockChecker::ReleaseAnyLock},
 
       // Destroy
-      {{{"mtx_destroy"}, 1}, &PthreadLockChecker::DestroyPthreadLock},
+      {{CDM::CLibrary, {"mtx_destroy"}, 1},
+       &PthreadLockChecker::DestroyPthreadLock},
   };
 
   ProgramStateRef resolvePossiblyDestroyedMutex(ProgramStateRef state,
@@ -258,13 +291,9 @@ REGISTER_MAP_WITH_PROGRAMSTATE(DestroyRetVal, const MemRegion *, SymbolRef)
 
 void PthreadLockChecker::checkPostCall(const CallEvent &Call,
                                        CheckerContext &C) const {
-  // An additional umbrella check that all functions modeled by this checker
-  // are global C functions.
-  // TODO: Maybe make this the default behavior of CallDescription
-  // with exactly one identifier?
   // FIXME: Try to handle cases when the implementation was inlined rather
   // than just giving up.
-  if (!Call.isGlobalCFunction() || C.wasInlined)
+  if (C.wasInlined)
     return;
 
   if (const FnCheck *Callback = PThreadCallbacks.lookup(Call))
diff --git a/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
index 50d50562d3e756..5152624d00f466 100644
--- a/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
@@ -52,8 +52,8 @@ class SimpleStreamChecker : public Checker<check::PostCall,
                                            check::PreCall,
                                            check::DeadSymbols,
                                            check::PointerEscape> {
-  const CallDescription OpenFn{{"fopen"}, 2};
-  const CallDescription CloseFn{{"fclose"}, 1};
+  const CallDescription OpenFn{CDM::CLibrary, {"fopen"}, 2};
+  const CallDescription CloseFn{CDM::CLibrary, {"fclose"}, 1};
 
   const BugType DoubleCloseBugType{this, "Double fclose",
                                    "Unix Stream API Error"};
@@ -92,9 +92,6 @@ REGISTER_MAP_WITH_PROGRAMSTATE(StreamMap, SymbolRef, StreamState)
 
 void SimpleStreamChecker::checkPostCall(const CallEvent &Call,
                                         CheckerContext &C) const {
-  if (!Call.isGlobalCFunction())
-    return;
-
   if (!OpenFn.matches(Call))
     return;
 
@@ -111,9 +108,6 @@ void SimpleStreamChecker::checkPostCall(const CallEvent &Call,
 
 void SimpleStreamChecker::checkPreCall(const CallEvent &Call,
                                        CheckerContext &C) const {
-  if (!Call.isGlobalCFunction())
-    return;
-
   if (!CloseFn.matches(Call))
     return;
 
diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 31c756ab0c5812..bd495cd0f9710d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -302,85 +302,88 @@ class StreamChecker : public Checker<check::PreCall, eval::Call,
 
 private:
   CallDescriptionMap<FnDescription> FnDescriptions = {
-      {{{"fopen"}, 2}, {nullptr, &StreamChecker::evalFopen, ArgNone}},
-      {{{"fdopen"}, 2}, {nullptr, &StreamChecker::evalFopen, ArgNone}},
-      {{{"freopen"}, 3},
+      {{CDM::CLibrary, {"fopen"}, 2},
+       {nullptr, &StreamChecker::evalFopen, ArgNone}},
+      {{CDM::CLibrary, {"fdopen"}, 2},
+       {nullptr, &StreamChecker::evalFopen, ArgNone}},
+      {{CDM::CLibrary, {"freopen"}, 3},
        {&StreamChecker::preFreopen, &StreamChecker::evalFreopen, 2}},
-      {{{"tmpfile"}, 0}, {nullptr, &StreamChecker::evalFopen, ArgNone}},
-      {{{"fclose"}, 1},
+      {{CDM::CLibrary, {"tmpfile"}, 0},
+       {nullptr, &StreamChecker::evalFopen, ArgNone}},
+      {{CDM::CLibrary, {"fclose"}, 1},
        {&StreamChecker::preDefault, &StreamChecker::evalFclose, 0}},
-      {{{"fread"}, 4},
+      {{CDM::CLibrary, {"fread"}, 4},
        {&StreamChecker::preRead,
         std::bind(&StreamChecker::evalFreadFwrite, _1, _2, _3, _4, true), 3}},
-      {{{"fwrite"}, 4},
+      {{CDM::CLibrary, {"fwrite"}, 4},
        {&StreamChecker::preWrite,
         std::bind(&StreamChecker::evalFreadFwrite, _1, _2, _3, _4, false), 3}},
-      {{{"fgetc"}, 1},
+      {{CDM::CLibrary, {"fgetc"}, 1},
        {&StreamChecker::preRead,
         std::bind(&StreamChecker::evalFgetx, _1, _2, _3, _4, true), 0}},
-      {{{"fgets"}, 3},
+      {{CDM::CLibrary, {"fgets"}, 3},
        {&StreamChecker::preRead,
         std::bind(&StreamChecker::evalFgetx, _1, _2, _3, _4, false), 2}},
-      {{{"getc"}, 1},
+      {{CDM::CLibrary, {"getc"}, 1},
        {&StreamChecker::preRead,
         std::bind(&StreamChecker::evalFgetx, _1, _2, _3, _4, true), 0}},
-      {{{"fputc"}, 2},
+      {{CDM::CLibrary, {"fputc"}, 2},
        {&StreamChecker::preWrite,
         std::bind(&StreamChecker::evalFputx, _1, _2, _3, _4, true), 1}},
-      {{{"fputs"}, 2},
+      {{CDM::CLibrary, {"fputs"}, 2},
        {&StreamChecker::preWrite,
         std::bind(&StreamChecker::evalFputx, _1, _2, _3, _4, false), 1}},
-      {{{"putc"}, 2},
+      {{CDM::CLibrary, {"putc"}, 2},
        {&StreamChecker::preWrite,
         std::bind(&StreamChecker::evalFputx, _1, _2, _3, _4, true), 1}},
-      {{{"fprintf"}},
+      {{CDM::CLibrary, {"fprintf"}},
        {&StreamChecker::preWrite,
         std::bind(&StreamChecker::evalFprintf, _1, _2, _3, _4), 0}},
-      {{{"vfprintf"}, 3},
+      {{CDM::CLibrary, {"vfprintf"}, 3},
        {&StreamChecker::preWrite,
         std::bind(&StreamChecker::evalFprintf, _1, _2, _3, _4), 0}},
-      {{{"fscanf"}},
+      {{CDM::CLibrary, {"fscanf"}},
        {&StreamChecker::preRead,
         std::bind(&StreamChecker::evalFscanf, _1, _2, _3, _4), 0}},
-      {{{"vfscanf"}, 3},
+      {{CDM::CLibrary, {"vfscanf"}, 3},
        {&StreamChecker::preRead,
         std::bind(&StreamChecker::evalFscanf, _1, _2, _3, _4), 0}},
-      {{{"ungetc"}, 2},
+      {{CDM::CLibrary, {"ungetc"}, 2},
        {&StreamChecker::preWrite,
         std::bind(&StreamChecker::evalUngetc, _1, _2, _3, _4), 1}},
-      {{{"getdelim"}, 4},
+      {{CDM::CLibrary, {"getdelim"}, 4},
        {&StreamChecker::preRead,
         std::bind(&StreamChecker::evalGetdelim, _1, _2, _3, _4), 3}},
-      {{{"getline"}, 3},
+      {{CDM::CLibrary, {"getline"}, 3},
        {&StreamChecker::preRead,
         std::bind(&StreamChecker::evalGetdelim, _1, _2, _3, _4), 2}},
-      {{{"fseek"}, 3},
+      {{CDM::CLibrary, {"fseek"}, 3},
        {&StreamChecker::preFseek, &StreamChecker::evalFseek, 0}},
-      {{{"fseeko"}, 3},
+      {{CDM::CLibrary, {"fseeko"}, 3},
        {&StreamChecker::preFseek, &StreamChecker::evalFseek, 0}},
-      {{{"ftell"}, 1},
+      {{CDM::CLibrary, {"ftell"}, 1},
        {&StreamChecker::preWrite, &StreamChecker::evalFtell, 0}},
-      {{{"ftello"}, 1},
+      {{CDM::CLibrary, {"ftello"}, 1},
        {&StreamChecker::preWrite, &StreamChecker::evalFtell, 0}},
-      {{{"fflush"}, 1},
+      {{CDM::CLibrary, {"fflush"}, 1},
        {&StreamChecker::preFflush, &StreamChecker::evalFflush, 0}},
-      {{{"rewind"}, 1},
+      {{CDM::CLibrary, {"rewind"}, 1},
        {&StreamChecker::preDefault, &StreamChecker::evalRewind, 0}},
-      {{{"fgetpos"}, 2},
+      {{CDM::CLibrary, {"fgetpos"}, 2},
        {&StreamChecker::preWrite, &StreamChecker::evalFgetpos, 0}},
-      {{{"fsetpos"}, 2},
+      {{CDM::CLibrary, {"fsetpos"}, 2},
        {&StreamChecker::preDefault, &StreamChecker::evalFsetpos, 0}},
-      {{{"clearerr"}, 1},
+      {{CDM::CLibrary, {"clearerr"}, 1},
        {&StreamChecker::preDefault, &StreamChecker::evalClearerr, 0}},
-      {{{"feof"}, 1},
+      {{CDM::CLibrary, {"feof"}, 1},
        {&StreamChecker::preDefault,
         std::bind(&StreamChecker::evalFeofFerror, _1, _2, _3, _4, ErrorFEof),
         0}},
-      {{{"ferror"}, 1},
+      {{CDM::CLibrary, {"ferror"}, 1},
        {&StreamChecker::preDefault,
         std::bind(&StreamChecker::evalFeofFerror, _1, _2, _3, _4, ErrorFError),
         0}},
-      {{{"fileno"}, 1},
+      {{CDM::CLibrary, {"fileno"}, 1},
        {&StreamChecker::preDefault, &StreamChecker::evalFileno, 0}},
   };
 
@@ -540,8 +543,6 @@ class StreamChecker : public Checker<check::PreCall, eval::Call,
   const FnDescription *lookupFn(const CallEvent &Call) const {
     // Recognize "global C functions" with only integral or pointer arguments
     // (and matching name) as stream functions.
-    if (!Call.isGlobalCFunction())
-      return nullptr;
     for (auto *P : Call.parameters()) {
       QualType T = P->getType();
       if (!T->isIntegralOrEnumerationType() && !T->isPointerType() &&
diff --git a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
index 2d1b873abf73f0..28320f46f237ac 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
@@ -100,32 +100,31 @@ class ValistChecker : public Checker<check::PreCall, check::PreStmt<VAArgExpr>,
 };
 
 const SmallVector<ValistChecker::VAListAccepter, 15>
-    ValistChecker::VAListAccepters = {{{{"vfprintf"}, 3}, 2},
-                                      {{{"vfscanf"}, 3}, 2},
-                                      {{{"vprintf"}, 2}, 1},
-                                      {{{"vscanf"}, 2}, 1},
-                                      {{{"vsnprintf"}, 4}, 3},
-                                      {{{"vsprintf"}, 3}, 2},
-                                      {{{"vsscanf"}, 3}, 2},
-                                      {{{"vfwprintf"}, 3}, 2},
-                                      {{{"vfwscanf"}, 3}, 2},
-                                      {{{"vwprintf"}, 2}, 1},
-                                      {{{"vwscanf"}, 2}, 1},
-                                      {{{"vswprintf"}, 4}, 3},
+    ValistChecker::VAListAccepters = {{{CDM::CLibrary, {"vfprintf"}, 3}, 2},
+                                      {{CDM::CLibrary, {"vfscanf"}, 3}, 2},
+                                      {{CDM::CLibrary, {"vprintf"}, 2}, 1},
+                                      {{CDM::CLibrary, {"vscanf"}, 2}, 1},
+                                      {{CDM::CLibrary, {"vsnprintf"}, 4}, 3},
+                                      {{CDM::CLibrary, {"vsprintf"}, 3}, 2},
+                                      {{CDM::CLibrary, {"vsscanf"}, 3}, 2},
+                                      {{CDM::CLibrary, {"vfwprintf"}, 3}, 2},
+                                      {{CDM::CLibrary, {"vfwscanf"}, 3}, 2},
+                                      {{CDM::CLibrary, {"vwprintf"}, 2}, 1},
+                                      {{CDM::CLibrary, {"vwscanf"}, 2}, 1},
+                                      {{CDM::CLibrary, {"vswprintf"}, 4}, 3},
                                       // vswprintf is the wide version of
                                       // vsnprintf, vsprintf has no wide version
-                                      {{{"vswscanf"}, 3}, 2}};
+                                      {{CDM::CLibrary, {"vswscanf"}, 3}, 2}};
 
-const CallDescription ValistChecker::VaStart({"__builtin_va_start"}, /*Args=*/2,
+const CallDescription ValistChecker::VaStart(CDM::CLibrary,
+                                             {"__builtin_va_start"}, /*Args=*/2,
                                              /*Params=*/1),
-    ValistChecker::VaCopy({"__builtin_va_copy"}, 2),
-    ValistChecker::VaEnd({"__builtin_va_end"}, 1);
+    ValistChecker::VaCopy(CDM::CLibrary, {"__builtin_va_copy"}, 2),
+    ValistChecker::VaEnd(CDM::CLibrary, {"__builtin_va_end"}, 1);
 } // end anonymous namespace
 
 void ValistChecker::checkPreCall(const CallEvent &Call,
                   ...
[truncated]

Copy link
Contributor

@Szelethus Szelethus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a very straightforward followup to the existing patches.

@NagyDonat NagyDonat merged commit fe3b20d into llvm:main Apr 11, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:static analyzer clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants