Skip to content

Commit 99e07ce

Browse files
committed
WIP Impl thread modeling checker
1 parent 41ec6ff commit 99e07ce

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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

Comments
 (0)