22 using namespace clang;
26 class ObjCAtSyncChecker
27 :
public Checker< check::PreStmt<ObjCAtSynchronizedStmt> > {
28 mutable std::unique_ptr<BuiltinBug> BT_null;
29 mutable std::unique_ptr<BuiltinBug> BT_undef;
37 CheckerContext &C)
const {
39 const Expr *Ex = S->getSynchExpr();
41 SVal
V =
C.getSVal(Ex);
44 if (isa<UndefinedVal>(
V)) {
45 if (ExplodedNode *N =
C.generateErrorNode()) {
47 BT_undef.reset(
new BuiltinBug(
this,
"Uninitialized value used as mutex "
48 "for @synchronized"));
49 auto report = std::make_unique<PathSensitiveBugReport>(
50 *BT_undef, BT_undef->getDescription(), N);
52 C.emitReport(std::move(report));
62 std::tie(notNullState, nullState) =
state->assume(
V.castAs<DefinedSVal>());
68 if (ExplodedNode *N =
C.generateNonFatalErrorNode(nullState)) {
70 BT_null.reset(
new BuiltinBug(
71 this,
"Nil value used as mutex for @synchronized() "
72 "(no synchronization will occur)"));
73 auto report = std::make_unique<PathSensitiveBugReport>(
74 *BT_null, BT_null->getDescription(), N);
77 C.emitReport(std::move(report));
87 C.addTransition(notNullState);
90 void ento::registerObjCAtSyncChecker(CheckerManager &mgr) {
91 mgr.registerChecker<ObjCAtSyncChecker>();
94 bool ento::shouldRegisterObjCAtSyncChecker(
const CheckerManager &mgr) {