30 using namespace clang;
35 class NonnullGlobalConstantsChecker :
public Checker<check::Location> {
41 NonnullGlobalConstantsChecker() {}
43 void checkLocation(SVal l,
bool isLoad,
const Stmt *S,
44 CheckerContext &C)
const;
47 void initIdentifierInfo(
ASTContext &Ctx)
const;
49 bool isGlobalConstString(SVal
V)
const;
51 bool isNonnullType(
QualType Ty)
const;
57 void NonnullGlobalConstantsChecker::initIdentifierInfo(
ASTContext &Ctx)
const {
62 CFStringRefII = &Ctx.
Idents.
get(
"CFStringRef");
63 CFBooleanRefII = &Ctx.
Idents.
get(
"CFBooleanRef");
67 void NonnullGlobalConstantsChecker::checkLocation(SVal location,
bool isLoad,
69 CheckerContext &C)
const {
70 initIdentifierInfo(C.getASTContext());
71 if (!isLoad || !location.isValid())
76 if (isGlobalConstString(location)) {
77 SVal
V = State->getSVal(location.castAs<Loc>());
84 C.addTransition(OutputState);
91 bool NonnullGlobalConstantsChecker::isGlobalConstString(SVal V)
const {
95 auto *Region = dyn_cast<VarRegion>(RegionVal->getAsRegion());
105 if (isNonnullType(Ty) && HasConst)
110 if (
const auto *TT = dyn_cast<TypedefType>(T)) {
111 Ty = TT->getDecl()->getUnderlyingType();
115 if (isNonnullType(Ty) && HasConst)
117 }
else if (
const auto *AT = dyn_cast<AttributedType>(T)) {
118 if (AT->getAttrKind() == attr::TypeNonNull)
120 Ty = AT->getModifiedType();
129 bool NonnullGlobalConstantsChecker::isNonnullType(
QualType Ty)
const {
134 if (
auto *T = dyn_cast<ObjCObjectPointerType>(Ty)) {
135 return T->getInterfaceDecl() &&
136 T->getInterfaceDecl()->getIdentifier() == NSStringII;
137 }
else if (
auto *T = dyn_cast<TypedefType>(Ty)) {
139 return II == CFStringRefII || II == CFBooleanRefII;
144 void ento::registerNonnullGlobalConstantsChecker(CheckerManager &Mgr) {
145 Mgr.registerChecker<NonnullGlobalConstantsChecker>();
148 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