diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp index c5437b16c688..72c6a869d225 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp @@ -26,6 +26,7 @@ #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" +#include <optional> using namespace clang; using namespace ento; @@ -77,7 +78,8 @@ void NonnullGlobalConstantsChecker::checkLocation(SVal location, bool isLoad, if (isGlobalConstString(location)) { SVal V = State->getSVal(location.castAs<Loc>()); - Optional<DefinedOrUnknownSVal> Constr = V.getAs<DefinedOrUnknownSVal>(); + std::optional<DefinedOrUnknownSVal> Constr = + V.getAs<DefinedOrUnknownSVal>(); if (Constr) { @@ -91,7 +93,7 @@ void NonnullGlobalConstantsChecker::checkLocation(SVal location, bool isLoad, /// \param V loaded lvalue. /// \return whether @c val is a string-like const global. bool NonnullGlobalConstantsChecker::isGlobalConstString(SVal V) const { - Optional<loc::MemRegionVal> RegionVal = V.getAs<loc::MemRegionVal>(); + std::optional<loc::MemRegionVal> RegionVal = V.getAs<loc::MemRegionVal>(); if (!RegionVal) return false; auto *Region = dyn_cast<VarRegion>(RegionVal->getAsRegion()); @@ -109,17 +111,20 @@ bool NonnullGlobalConstantsChecker::isGlobalConstString(SVal V) const { // Look through the typedefs. while (const Type *T = Ty.getTypePtr()) { - if (const auto *TT = dyn_cast<TypedefType>(T)) { + if (const auto *AT = dyn_cast<AttributedType>(T)) { + if (AT->getAttrKind() == attr::TypeNonNull) + return true; + Ty = AT->getModifiedType(); + } else if (const auto *ET = dyn_cast<ElaboratedType>(T)) { + const auto *TT = dyn_cast<TypedefType>(ET->getNamedType()); + if (!TT) + return false; Ty = TT->getDecl()->getUnderlyingType(); // It is sufficient for any intermediate typedef // to be classified const. HasConst = HasConst || Ty.isConstQualified(); if (isNonnullType(Ty) && HasConst) return true; - } else if (const auto *AT = dyn_cast<AttributedType>(T)) { - if (AT->getAttrKind() == attr::TypeNonNull) - return true; - Ty = AT->getModifiedType(); } else { return false; } @@ -136,7 +141,7 @@ bool NonnullGlobalConstantsChecker::isNonnullType(QualType Ty) const { if (auto *T = dyn_cast<ObjCObjectPointerType>(Ty)) { return T->getInterfaceDecl() && T->getInterfaceDecl()->getIdentifier() == NSStringII; - } else if (auto *T = dyn_cast<TypedefType>(Ty)) { + } else if (auto *T = Ty->getAs<TypedefType>()) { IdentifierInfo* II = T->getDecl()->getIdentifier(); return II == CFStringRefII || II == CFBooleanRefII || II == CFNullRefII; } |