diff --git a/clang/include/clang/Analysis/AnalysisDeclContext.h b/clang/include/clang/Analysis/AnalysisDeclContext.h --- a/clang/include/clang/Analysis/AnalysisDeclContext.h +++ b/clang/include/clang/Analysis/AnalysisDeclContext.h @@ -229,7 +229,9 @@ protected: LocationContext(ContextKind k, AnalysisDeclContext *ctx, const LocationContext *parent, int64_t ID) - : Kind(k), Ctx(ctx), Parent(parent), ID(ID) {} + : Kind(k), Ctx(ctx), Parent(parent), ID(ID) { + assert(ctx); + } public: virtual ~LocationContext(); @@ -238,8 +240,10 @@ int64_t getID() const { return ID; } + LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; } + /// It might return null. const LocationContext *getParent() const { return Parent; } bool isParentOf(const LocationContext *LC) const; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -66,10 +66,14 @@ public: LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r) : store(st), region(r) { + assert(r); assert(NonLoc::isCompoundType(r->getValueType())); } + /// It might return null. const void *getStore() const { return store.getStore(); } + + LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion *getRegion() const { return region; } static void Profile(llvm::FoldingSetNodeID& ID, @@ -86,7 +90,9 @@ public: PointerToMemberData(const NamedDecl *D, llvm::ImmutableList L) - : D(D), L(L) {} + : D(D), L(L) { + assert(D); + } using iterator = llvm::ImmutableList::iterator; @@ -97,6 +103,8 @@ llvm::ImmutableList L); void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, D, L); } + + LLVM_ATTRIBUTE_RETURNS_NONNULL const NamedDecl *getDeclaratorDecl() const { return D; } llvm::ImmutableList getCXXBaseList() const { diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -256,6 +256,7 @@ /// @param IsPrunable Whether the note is prunable. It allows BugReporter /// to omit the note from the report if it would make the displayed /// bug path significantly shorter. + LLVM_ATTRIBUTE_RETURNS_NONNULL const NoteTag *getNoteTag(NoteTag::Callback &&Cb, bool IsPrunable = false) { return Eng.getDataTags().make(std::move(Cb), IsPrunable); } diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h @@ -112,6 +112,7 @@ /// /// Note that a ConstraintManager is not obligated to return a concretized /// value for a symbol, even if it is perfectly constrained. + /// It might return null. virtual const llvm::APSInt* getSymVal(ProgramStateRef state, SymbolRef sym) const { return nullptr; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h @@ -32,6 +32,7 @@ DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR); /// Get raw dynamic type information for the region \p MR. +/// It might return null. const DynamicTypeInfo *getRawDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR); diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -74,6 +74,7 @@ RegionOffset() = default; RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {} + /// It might return null. const MemRegion *getRegion() const { return R; } bool hasSymbolicOffset() const { return Offset == Symbolic; } @@ -114,22 +115,25 @@ virtual MemRegionManager &getMemRegionManager() const = 0; - const MemSpaceRegion *getMemorySpace() const; + LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion *getMemorySpace() const; - const MemRegion *getBaseRegion() const; + LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion *getBaseRegion() const; /// Recursively retrieve the region of the most derived class instance of /// regions of C++ base class instances. + LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion *getMostDerivedObjectRegion() const; /// Check if the region is a subregion of the given region. /// Each region is a subregion of itself. virtual bool isSubRegionOf(const MemRegion *R) const; + LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const; /// If this is a symbolic region, returns the region. Otherwise, /// goes up the base chain looking for the first symbolic base region. + /// It might return null. const SymbolicRegion *getSymbolicBase() const; bool hasGlobalsOrParametersStorage() const; @@ -169,7 +173,8 @@ Kind getKind() const { return kind; } template const RegionTy* getAs() const; - template const RegionTy* castAs() const; + template + LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *castAs() const; virtual bool isBoundable() const { return false; } @@ -268,6 +273,7 @@ void dumpToStream(raw_ostream &os) const override; + LLVM_ATTRIBUTE_RETURNS_NONNULL const CodeTextRegion *getCodeRegion() const { return CR; } static bool classof(const MemRegion *R) { @@ -391,6 +397,7 @@ } public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const StackFrameContext *getStackFrame() const { return SFC; } void Profile(llvm::FoldingSetNodeID &ID) const override; @@ -444,6 +451,7 @@ } public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion* getSuperRegion() const { return superRegion; } @@ -481,6 +489,7 @@ unsigned Cnt, const MemRegion *superRegion); public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const Expr *getExpr() const { return Ex; } bool isBoundable() const override { return true; } @@ -639,10 +648,12 @@ return locTy; } + LLVM_ATTRIBUTE_RETURNS_NONNULL const BlockDecl *getDecl() const { return BD; } + LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext *getAnalysisDeclContext() const { return AC; } void dumpToStream(raw_ostream &os) const override; @@ -674,6 +685,7 @@ : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), BlockCount(count) { assert(bc); + assert(bc->getDecl()); assert(lc); assert(isa(sreg) || isa(sreg) || @@ -685,8 +697,10 @@ const MemRegion *); public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const BlockCodeRegion *getCodeRegion() const { return BC; } + LLVM_ATTRIBUTE_RETURNS_NONNULL const BlockDecl *getDecl() const { return BC->getDecl(); } QualType getLocationType() const override { return BC->getLocationType(); } @@ -700,10 +714,12 @@ const MemRegion * const *originalR) : R(r), OriginalR(originalR) {} + LLVM_ATTRIBUTE_RETURNS_NONNULL const VarRegion *getCapturedRegion() const { return cast(*R); } + LLVM_ATTRIBUTE_RETURNS_NONNULL const VarRegion *getOriginalRegion() const { return cast(*OriginalR); } @@ -726,7 +742,7 @@ }; /// Return the original region for a captured region, if - /// one exists. + /// one exists. It might return null. const VarRegion *getOriginalRegion(const VarRegion *VR) const; referenced_vars_iterator referenced_vars_begin() const; @@ -769,6 +785,7 @@ } public: + /// It might return null. SymbolRef getSymbol() const { return sym; } bool isBoundable() const override { return true; } @@ -802,6 +819,7 @@ const MemRegion *superRegion); public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const StringLiteral *getStringLiteral() const { return Str; } QualType getValueType() const override { return Str->getType(); } @@ -836,6 +854,7 @@ const MemRegion *superRegion); public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const ObjCStringLiteral *getObjCStringLiteral() const { return Str; } QualType getValueType() const override { return Str->getType(); } @@ -882,6 +901,7 @@ void dumpToStream(raw_ostream &os) const override; + LLVM_ATTRIBUTE_RETURNS_NONNULL const CompoundLiteralExpr *getLiteralExpr() const { return CL; } static bool classof(const MemRegion* R) { @@ -896,6 +916,7 @@ } public: + // TODO what does this return? virtual const ValueDecl *getDecl() const = 0; static bool classof(const MemRegion* R) { @@ -919,8 +940,10 @@ } public: + // TODO what does this return? const VarDecl *getDecl() const override = 0; + /// It might return null. const StackFrameContext *getStackFrame() const; QualType getValueType() const override { @@ -948,6 +971,7 @@ // which, unlike everything else on this list, are not memory spaces. assert(isa(sReg) || isa(sReg) || isa(sReg) || isa(sReg)); + assert(vd); } static void ProfileRegion(llvm::FoldingSetNodeID &ID, const VarDecl *VD, @@ -956,6 +980,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) const override; + LLVM_ATTRIBUTE_RETURNS_NONNULL const VarDecl *getDecl() const override { return VD; } QualType getValueType() const override { @@ -993,12 +1018,14 @@ ParamVarRegion(const Expr *OE, unsigned Idx, const MemRegion *SReg) : VarRegion(SReg, ParamVarRegionKind), OriginExpr(OE), Index(Idx) { assert(!cast(SReg)->getStackFrame()->inTopFrame()); + assert(OriginExpr); } static void ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE, unsigned Idx, const MemRegion *SReg); public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const Expr *getOriginExpr() const { return OriginExpr; } unsigned getIndex() const { return Index; } @@ -1007,6 +1034,8 @@ void dumpToStream(raw_ostream &os) const override; QualType getValueType() const override; + + /// TODO: What does this return? const ParmVarDecl *getDecl() const override; bool canPrintPrettyAsExpr() const override; @@ -1058,7 +1087,9 @@ const FieldDecl *FD; FieldRegion(const FieldDecl *fd, const SubRegion *sReg) - : DeclRegion(sReg, FieldRegionKind), FD(fd) {} + : DeclRegion(sReg, FieldRegionKind), FD(fd) { + assert(FD); + } static void ProfileRegion(llvm::FoldingSetNodeID &ID, const FieldDecl *FD, const MemRegion* superRegion) { @@ -1068,6 +1099,7 @@ } public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const FieldDecl *getDecl() const override { return FD; } void Profile(llvm::FoldingSetNodeID &ID) const override; @@ -1100,6 +1132,7 @@ const MemRegion* superRegion); public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const ObjCIvarDecl *getDecl() const override; void Profile(llvm::FoldingSetNodeID& ID) const override; @@ -1132,6 +1165,8 @@ public: // FIXME: Eventually support symbolic offsets. CharUnits getOffset() const { return Offset; } + + // It might return null. const MemRegion *getRegion() const { return Region; } void dumpToStream(raw_ostream &os) const; @@ -1194,6 +1229,7 @@ Expr const *E, const MemRegion *sReg); public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const Expr *getExpr() const { return Ex; } QualType getValueType() const override { return Ex->getType(); } @@ -1224,6 +1260,7 @@ bool IsVirtual, const MemRegion *SReg); public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const CXXRecordDecl *getDecl() const { return Data.getPointer(); } bool isVirtual() const { return Data.getInt(); } @@ -1266,6 +1303,7 @@ const MemRegion *SReg); public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const CXXRecordDecl *getDecl() const { return DerivedD; } QualType getValueType() const override; @@ -1291,8 +1329,8 @@ return nullptr; } -template -const RegionTy* MemRegion::castAs() const { +template +LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *MemRegion::castAs() const { return cast(this); } diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -271,6 +271,7 @@ ConditionTruthVal areEqual(SVal Lhs, SVal Rhs) const; /// Utility method for getting regions. + LLVM_ATTRIBUTE_RETURNS_NONNULL const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const; //==---------------------------------------------------------------------==// diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -313,6 +313,7 @@ assert(!Loc::isLocType(sym->getType())); } + LLVM_ATTRIBUTE_RETURNS_NONNULL SymbolRef getSymbol() const { return (const SymExpr *) Data; } @@ -384,9 +385,12 @@ class CompoundVal : public NonLoc { friend class ento::SValBuilder; - explicit CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {} + explicit CompoundVal(const CompoundValData *D) : NonLoc(CompoundValKind, D) { + assert(D); + } public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const CompoundValData* getValue() const { return static_cast(Data); } @@ -407,14 +411,20 @@ friend class ento::SValBuilder; explicit LazyCompoundVal(const LazyCompoundValData *D) - : NonLoc(LazyCompoundValKind, D) {} + : NonLoc(LazyCompoundValKind, D) { + assert(D); + } public: + LLVM_ATTRIBUTE_RETURNS_NONNULL const LazyCompoundValData *getCVData() const { return static_cast(Data); } + LLVM_ATTRIBUTE_RETURNS_NONNULL const void *getStore() const; + + LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion *getRegion() const; static bool classof(SVal V) { diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h @@ -98,6 +98,7 @@ /// the beginning of the analysis, and SymbolDerived which denotes the value /// of a certain memory region after its super region (a memory space or /// a larger record region) is default-bound with a certain symbol. + /// It might return null. virtual const MemRegion *getOriginRegion() const { return nullptr; } }; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -48,6 +48,7 @@ assert(isValidTypeForSymbol(r->getValueType())); } + LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion* getRegion() const { return R; } static void Profile(llvm::FoldingSetNodeID& profile, const TypedValueRegion* R) { @@ -95,8 +96,10 @@ assert(isValidTypeForSymbol(t)); } + /// It might return null. const Stmt *getStmt() const { return S; } unsigned getCount() const { return Count; } + /// It might return null. const void *getTag() const { return SymbolTag; } QualType getType() const override; @@ -140,7 +143,9 @@ assert(isValidTypeForSymbol(r->getValueType())); } + LLVM_ATTRIBUTE_RETURNS_NONNULL SymbolRef getParentSymbol() const { return parentSymbol; } + LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion *getRegion() const { return R; } QualType getType() const override; @@ -179,6 +184,7 @@ assert(r); } + LLVM_ATTRIBUTE_RETURNS_NONNULL const SubRegion *getRegion() const { return R; } QualType getType() const override; @@ -226,29 +232,37 @@ assert(tag); } - const MemRegion *getRegion() const { return R; } - const Stmt *getStmt() const { return S; } - const LocationContext *getLocationContext() const { return LCtx; } - unsigned getCount() const { return Count; } - const void *getTag() const { return Tag; } + LLVM_ATTRIBUTE_RETURNS_NONNULL + const MemRegion *getRegion() const { return R; } - QualType getType() const override; + LLVM_ATTRIBUTE_RETURNS_NONNULL + const Stmt *getStmt() const { return S; } - StringRef getKindStr() const override; + LLVM_ATTRIBUTE_RETURNS_NONNULL + const LocationContext *getLocationContext() const { return LCtx; } - void dumpToStream(raw_ostream &os) const override; + unsigned getCount() const { return Count; } - static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R, - const Stmt *S, QualType T, const LocationContext *LCtx, - unsigned Count, const void *Tag) { - profile.AddInteger((unsigned) SymbolMetadataKind); - profile.AddPointer(R); - profile.AddPointer(S); - profile.Add(T); - profile.AddPointer(LCtx); - profile.AddInteger(Count); - profile.AddPointer(Tag); - } + LLVM_ATTRIBUTE_RETURNS_NONNULL + const void *getTag() const { return Tag; } + + QualType getType() const override; + + StringRef getKindStr() const override; + + void dumpToStream(raw_ostream &os) const override; + + static void Profile(llvm::FoldingSetNodeID &profile, const MemRegion *R, + const Stmt *S, QualType T, const LocationContext *LCtx, + unsigned Count, const void *Tag) { + profile.AddInteger((unsigned)SymbolMetadataKind); + profile.AddPointer(R); + profile.AddPointer(S); + profile.Add(T); + profile.AddPointer(LCtx); + profile.AddInteger(Count); + profile.AddPointer(Tag); + } void Profile(llvm::FoldingSetNodeID& profile) override { Profile(profile, R, S, T, LCtx, Count, Tag); @@ -287,6 +301,7 @@ QualType getType() const override { return ToTy; } + LLVM_ATTRIBUTE_RETURNS_NONNULL const SymExpr *getOperand() const { return Operand; } void dumpToStream(raw_ostream &os) const override; @@ -587,6 +602,7 @@ SymbolManager &symmgr, StoreManager &storeMgr) : LCtx(Ctx), Loc(s), SymMgr(symmgr), reapedStore(nullptr, storeMgr) {} + /// It might return null. const LocationContext *getLocationContext() const { return LCtx; } bool isLive(SymbolRef sym); diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -162,7 +162,9 @@ } ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg) - : DeclRegion(sReg, ObjCIvarRegionKind), IVD(ivd) {} + : DeclRegion(sReg, ObjCIvarRegionKind), IVD(ivd) { + assert(IVD); +} const ObjCIvarDecl *ObjCIvarRegion::getDecl() const { return IVD; }