31 using namespace clang;
36 class NonnullGlobalConstantsChecker :
public Checker<check::Location> {
42 NonnullGlobalConstantsChecker() {}
44 void checkLocation(SVal l,
bool isLoad,
const Stmt *S,
45 CheckerContext &C)
const;
48 void initIdentifierInfo(
ASTContext &Ctx)
const;
50 bool isGlobalConstString(SVal V)
const;
52 bool isNonnullType(
QualType Ty)
const;
58 void NonnullGlobalConstantsChecker::initIdentifierInfo(
ASTContext &Ctx)
const {
63 CFStringRefII = &Ctx.
Idents.
get(
"CFStringRef");
64 CFBooleanRefII = &Ctx.
Idents.
get(
"CFBooleanRef");
68 void NonnullGlobalConstantsChecker::checkLocation(SVal location,
bool isLoad,
70 CheckerContext &C)
const {
71 initIdentifierInfo(C.getASTContext());
72 if (!isLoad || !location.isValid())
77 if (isGlobalConstString(location)) {
78 SVal V = State->getSVal(location.castAs<Loc>());
85 C.addTransition(OutputState);
92 bool NonnullGlobalConstantsChecker::isGlobalConstString(SVal V)
const {
96 auto *Region = dyn_cast<VarRegion>(RegionVal->getAsRegion());
106 if (isNonnullType(Ty) && HasConst)
110 while (
auto *T = dyn_cast<TypedefType>(Ty)) {
111 Ty = T->getDecl()->getUnderlyingType();
116 if (isNonnullType(Ty) && HasConst)
123 bool NonnullGlobalConstantsChecker::isNonnullType(
QualType Ty)
const {
128 if (
auto *T = dyn_cast<ObjCObjectPointerType>(Ty)) {
129 return T->getInterfaceDecl() &&
130 T->getInterfaceDecl()->getIdentifier() == NSStringII;
131 }
else if (
auto *T = dyn_cast<TypedefType>(Ty)) {
133 return II == CFStringRefII || II == CFBooleanRefII;
138 void ento::registerNonnullGlobalConstantsChecker(CheckerManager &Mgr) {
139 Mgr.registerChecker<NonnullGlobalConstantsChecker>();
A (possibly-)qualified type.
Stmt - This represents one statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Decl - This represents one declaration (or definition), e.g.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
Represents a variable declaration or definition.
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isConstQualified() const
Determine whether this type is const-qualified.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Dataflow Directional Tag Classes.
bool isPointerType() const