26#include "llvm/ADT/SmallString.h"
27#include "llvm/ADT/StringSwitch.h"
28#include "llvm/Support/raw_ostream.h"
34class MacOSXAPIChecker :
public Checker< check::PreStmt<CallExpr> > {
35 const BugType BT_dispatchOnce{
this,
"Improper use of 'dispatch_once'",
44 StringRef FName)
const;
48 StringRef FName)
const;
57MacOSXAPIChecker::getParentIvarRegion(
const MemRegion *R) {
58 const SubRegion *SR = dyn_cast<SubRegion>(R);
68 StringRef FName)
const {
81 if (isa<GlobalsSpaceRegion>(RS))
89 StringRef TrimmedFName = FName.ltrim(
'_');
90 if (TrimmedFName != FName)
95 llvm::raw_svector_ostream os(S);
96 bool SuggestStatic =
false;
97 os <<
"Call to '" << FName <<
"' uses";
98 if (
const VarRegion *VR = dyn_cast<VarRegion>(RB)) {
99 const VarDecl *VD = VR->getDecl();
109 os <<
" memory within";
111 os <<
" the block variable '";
113 os <<
" the local variable '";
114 os << VR->getDecl()->
getName() <<
'\'';
115 SuggestStatic =
true;
118 os <<
" memory within";
119 os <<
" the instance variable '" << IVR->getDecl()->getName() <<
'\'';
120 }
else if (isa<HeapSpaceRegion>(RS)) {
121 os <<
" heap-allocated memory";
122 }
else if (isa<UnknownSpaceRegion>(RS)) {
130 os <<
" stack allocated memory";
132 os <<
" for the predicate value. Using such transient memory for "
133 "the predicate is potentially dangerous.";
135 os <<
" Perhaps you intended to declare the variable as 'static'?";
142 std::make_unique<PathSensitiveBugReport>(BT_dispatchOnce, os.str(), N);
144 C.emitReport(std::move(report));
151void MacOSXAPIChecker::checkPreStmt(
const CallExpr *CE,
153 StringRef Name =
C.getCalleeName(CE);
158 llvm::StringSwitch<SubChecker>(Name)
159 .Cases(
"dispatch_once",
162 &MacOSXAPIChecker::CheckDispatchOnce)
166 (this->*SC)(
C, CE, Name);
177bool ento::shouldRegisterMacOSXAPIChecker(
const CheckerManager &mgr) {
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Represents a variable declaration or definition.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
SubRegion - A region that subsets another larger region.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const
Defines the clang::TargetInfo interface.
const char *const AppleAPIMisuse
The JSON file list parser is used to communicate input to InstallAPI.