1+
2+
3+ #include " clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
4+ #include " clang/StaticAnalyzer/Core/BugReporter/BugType.h"
5+ #include " clang/StaticAnalyzer/Core/Checker.h"
6+ #include " clang/StaticAnalyzer/Core/CheckerManager.h"
7+ #include " clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
8+ #include " clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
9+
10+ #include < clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h>
11+
12+ using namespace clang ;
13+ using namespace ento ;
14+
15+ namespace {
16+
17+ // Since we are looking to extract the arguments, go with pre call for now
18+ class ThreadModeling : public Checker <check::PreCall> {
19+
20+ constexpr static CallDescriptionSet ThreadCreateCalls {
21+ { CDM::CLibrary, {" pthread_create" }, 4 },
22+ };
23+
24+ const FunctionDecl *GetFunctionDecl (SVal V, CheckerContext &C) const ;
25+ public:
26+ void checkPreCall (const CallEvent &Call, CheckerContext &C) const ;
27+ };
28+
29+ } // end anonymous namespace
30+
31+
32+ void ThreadModeling::checkPreCall (const CallEvent &Call, CheckerContext &C) const {
33+ if (!ThreadCreateCalls.contains (Call)) {
34+ return ;
35+ }
36+
37+ // 1. Get the `start_routine` argument
38+ ProgramStateRef State = C.getState ();
39+ const FunctionDecl *CreateCall = reinterpret_cast <const FunctionDecl*>(Call.getDecl ());
40+
41+ // 2. Extract the start_routine parameter
42+ /* int pthread_create(pthread_t *restrict thread,
43+ const pthread_attr_t *restrict attr,
44+ void *(*start_routine)(void *),
45+ void *restrict arg);
46+ */
47+ assert (Call.getNumArgs () == 4 && " pthread_create(3) should have 4 arguments" );
48+ const Expr *StartRoutineExpr = Call.getArgExpr (2 );
49+ assert (StartRoutineExpr && " start_routine should exist" ); // XXX: might fail if in diff TU?
50+
51+ // 3. Get the function pointer for `start_routine`
52+ const SVal SRV = C.getSVal (StartRoutineExpr);
53+
54+ // 4. Resolve FunctionDecl
55+ // 5. Get AST (single TU for now)
56+ // 6. Resolve AST to Call
57+ // 7. Inline Call
58+
59+
60+ }
61+
62+ const FunctionDecl *ThreadModeling::GetFunctionDecl (SVal V, CheckerContext &C) const {
63+ if (const FunctionDecl *FD = V.getAsFunctionDecl ())
64+ return FD;
65+ return nullptr ;
66+ }
67+
68+ void clang::ento::registerThreadModeling (CheckerManager &Mgr) {
69+ Mgr.registerChecker <ThreadModeling>();
70+ }
71+
72+ bool clang::ento::shouldRegisterThreadModeling (const CheckerManager &) {
73+ return true ;
74+ }
0 commit comments