30 using namespace clang;
35 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");
65 CFNullRefII = &Ctx.
Idents.
get(
"CFNullRef");
69 void NonnullGlobalConstantsChecker::checkLocation(SVal location,
bool isLoad,
71 CheckerContext &C)
const {
72 initIdentifierInfo(C.getASTContext());
73 if (!isLoad || !location.isValid())
78 if (isGlobalConstString(location)) {
79 SVal
V = State->getSVal(location.castAs<Loc>());
86 C.addTransition(OutputState);
93 bool NonnullGlobalConstantsChecker::isGlobalConstString(SVal V)
const {
97 auto *Region = dyn_cast<VarRegion>(RegionVal->getAsRegion());
107 if (isNonnullType(Ty) && HasConst)
112 if (
const auto *TT = dyn_cast<TypedefType>(T)) {
113 Ty = TT->getDecl()->getUnderlyingType();
117 if (isNonnullType(Ty) && HasConst)
119 }
else if (
const auto *AT = dyn_cast<AttributedType>(T)) {
120 if (AT->getAttrKind() == attr::TypeNonNull)
122 Ty = AT->getModifiedType();
131 bool NonnullGlobalConstantsChecker::isNonnullType(
QualType Ty)
const {
136 if (
auto *T = dyn_cast<ObjCObjectPointerType>(Ty)) {
137 return T->getInterfaceDecl() &&
138 T->getInterfaceDecl()->getIdentifier() == NSStringII;
139 }
else if (
auto *T = dyn_cast<TypedefType>(Ty)) {
141 return II == CFStringRefII || II == CFBooleanRefII || II == CFNullRefII;
146 void ento::registerNonnullGlobalConstantsChecker(CheckerManager &Mgr) {
147 Mgr.registerChecker<NonnullGlobalConstantsChecker>();
150 bool ento::shouldRegisterNonnullGlobalConstantsChecker(
const LangOptions &LO) {
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
The base class of the type hierarchy.
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 ...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
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