clang  6.0.0svn
ObjCAtSyncChecker.cpp
Go to the documentation of this file.
1 //== ObjCAtSyncChecker.cpp - nil mutex checker for @synchronized -*- C++ -*--=//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This defines ObjCAtSyncChecker, a builtin check that checks for null pointers
11 // used as mutexes for @synchronized.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "ClangSACheckers.h"
16 #include "clang/AST/StmtObjC.h"
22 
23 using namespace clang;
24 using namespace ento;
25 
26 namespace {
27 class ObjCAtSyncChecker
28  : public Checker< check::PreStmt<ObjCAtSynchronizedStmt> > {
29  mutable std::unique_ptr<BuiltinBug> BT_null;
30  mutable std::unique_ptr<BuiltinBug> BT_undef;
31 
32 public:
33  void checkPreStmt(const ObjCAtSynchronizedStmt *S, CheckerContext &C) const;
34 };
35 } // end anonymous namespace
36 
37 void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
38  CheckerContext &C) const {
39 
40  const Expr *Ex = S->getSynchExpr();
42  SVal V = state->getSVal(Ex, C.getLocationContext());
43 
44  // Uninitialized value used for the mutex?
45  if (V.getAs<UndefinedVal>()) {
46  if (ExplodedNode *N = C.generateErrorNode()) {
47  if (!BT_undef)
48  BT_undef.reset(new BuiltinBug(this, "Uninitialized value used as mutex "
49  "for @synchronized"));
50  auto report =
51  llvm::make_unique<BugReport>(*BT_undef, BT_undef->getDescription(), N);
52  bugreporter::trackNullOrUndefValue(N, Ex, *report);
53  C.emitReport(std::move(report));
54  }
55  return;
56  }
57 
58  if (V.isUnknown())
59  return;
60 
61  // Check for null mutexes.
62  ProgramStateRef notNullState, nullState;
63  std::tie(notNullState, nullState) = state->assume(V.castAs<DefinedSVal>());
64 
65  if (nullState) {
66  if (!notNullState) {
67  // Generate an error node. This isn't a sink since
68  // a null mutex just means no synchronization occurs.
69  if (ExplodedNode *N = C.generateNonFatalErrorNode(nullState)) {
70  if (!BT_null)
71  BT_null.reset(new BuiltinBug(
72  this, "Nil value used as mutex for @synchronized() "
73  "(no synchronization will occur)"));
74  auto report =
75  llvm::make_unique<BugReport>(*BT_null, BT_null->getDescription(), N);
76  bugreporter::trackNullOrUndefValue(N, Ex, *report);
77 
78  C.emitReport(std::move(report));
79  return;
80  }
81  }
82  // Don't add a transition for 'nullState'. If the value is
83  // under-constrained to be null or non-null, assume it is non-null
84  // afterwards.
85  }
86 
87  if (notNullState)
88  C.addTransition(notNullState);
89 }
90 
91 void ento::registerObjCAtSyncChecker(CheckerManager &mgr) {
92  if (mgr.getLangOpts().ObjC2)
93  mgr.registerChecker<ObjCAtSyncChecker>();
94 }
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
Defines the Objective-C statement AST node classes.
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
bool isUnknown() const
Definition: SVals.h:125
Expr - This represents one expression.
Definition: Expr.h:106
Represents Objective-C&#39;s @synchronized statement.
Definition: StmtObjC.h:262
ExplodedNode * generateNonFatalErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Definition: SVals.h:100
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:63
Dataflow Directional Tag Classes.
const Expr * getSynchExpr() const
Definition: StmtObjC.h:290
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition: SVals.h:92
const ProgramStateRef & getState() const
bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R, bool IsArg=false, bool EnableNullFPSuppression=true)
Attempts to add visitors to trace a null or undefined value back to its point of origin, whether it is a symbol constrained to null or an explicit assignment.
const LangOptions & getLangOpts() const
const LocationContext * getLocationContext() const