[clang] [Thread Modeling]: Resolve function pointers (PR #123357)
Isaac Nudelman via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 17 07:34:45 PST 2025
https://github.com/nuudlman created https://github.com/llvm/llvm-project/pull/123357
None
>From 41ec6ffe545cb7a2b25bda5dbbeed094e478f7df Mon Sep 17 00:00:00 2001
From: Isaac Nudelman <isaac.nudelman at utexas.edu>
Date: Fri, 17 Jan 2025 09:31:04 -0600
Subject: [PATCH 1/2] Declare new thread modeling checker
---
clang/include/clang/StaticAnalyzer/Checkers/Checkers.td | 4 ++++
clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt | 1 +
2 files changed, 5 insertions(+)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 1361da46c3c81d..b91d6411451f02 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -383,6 +383,10 @@ def TrustReturnsNonnullChecker : Checker<"TrustReturnsNonnull">,
"are not null">,
Documentation<NotDocumented>;
+def ThreadModeling : Checker<"Thread">,
+ HelpText<"Make threaded code available to other checkers.">,
+ Documentation<NotDocumented>;
+
} // end "apiModeling"
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index fcbe8b864b6e41..41df8d9321c034 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -112,6 +112,7 @@ add_clang_library(clangStaticAnalyzerCheckers
Taint.cpp
TaintTesterChecker.cpp
TestAfterDivZeroChecker.cpp
+ ThreadModeling.cpp
TraversalChecker.cpp
TrustNonnullChecker.cpp
TrustReturnsNonnullChecker.cpp
>From 99e07ce2b390d1071cf9cd95655f60da8203ab88 Mon Sep 17 00:00:00 2001
From: Isaac Nudelman <isaac.nudelman at utexas.edu>
Date: Fri, 17 Jan 2025 09:31:23 -0600
Subject: [PATCH 2/2] WIP Impl thread modeling checker
---
.../Checkers/ThreadModeling.cpp | 74 +++++++++++++++++++
1 file changed, 74 insertions(+)
create mode 100644 clang/lib/StaticAnalyzer/Checkers/ThreadModeling.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/ThreadModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/ThreadModeling.cpp
new file mode 100644
index 00000000000000..d5d48a8dde69a6
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/ThreadModeling.cpp
@@ -0,0 +1,74 @@
+
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+
+#include <clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h>
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+
+// Since we are looking to extract the arguments, go with pre call for now
+class ThreadModeling : public Checker<check::PreCall> {
+
+ constexpr static CallDescriptionSet ThreadCreateCalls {
+ { CDM::CLibrary, {"pthread_create"}, 4},
+ };
+
+ const FunctionDecl *GetFunctionDecl(SVal V, CheckerContext &C) const;
+public:
+ void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
+};
+
+} // end anonymous namespace
+
+
+void ThreadModeling::checkPreCall(const CallEvent &Call, CheckerContext &C) const {
+ if (!ThreadCreateCalls.contains(Call)) {
+ return;
+ }
+
+ // 1. Get the `start_routine` argument
+ ProgramStateRef State = C.getState();
+ const FunctionDecl *CreateCall = reinterpret_cast<const FunctionDecl*>(Call.getDecl());
+
+ // 2. Extract the start_routine parameter
+ /* int pthread_create(pthread_t *restrict thread,
+ const pthread_attr_t *restrict attr,
+ void *(*start_routine)(void *),
+ void *restrict arg);
+ */
+ assert(Call.getNumArgs() == 4 && "pthread_create(3) should have 4 arguments");
+ const Expr *StartRoutineExpr = Call.getArgExpr(2);
+ assert(StartRoutineExpr && "start_routine should exist"); // XXX: might fail if in diff TU?
+
+ // 3. Get the function pointer for `start_routine`
+ const SVal SRV = C.getSVal(StartRoutineExpr);
+
+ // 4. Resolve FunctionDecl
+ // 5. Get AST (single TU for now)
+ // 6. Resolve AST to Call
+ // 7. Inline Call
+
+
+}
+
+const FunctionDecl *ThreadModeling::GetFunctionDecl(SVal V, CheckerContext &C) const {
+ if (const FunctionDecl *FD = V.getAsFunctionDecl())
+ return FD;
+ return nullptr;
+}
+
+void clang::ento::registerThreadModeling(CheckerManager &Mgr) {
+ Mgr.registerChecker<ThreadModeling>();
+}
+
+bool clang::ento::shouldRegisterThreadModeling(const CheckerManager &) {
+ return true;
+}
\ No newline at end of file
More information about the cfe-commits
mailing list