steakhal created this revision.
steakhal added reviewers: NoQ, martong, Szelethus.
Herald added subscribers: manas, ASDenysPetrov, dkrupp, donat.nagy, 
mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware, xazax.hun.
Herald added a project: All.
steakhal requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch annotates the most important analyzer function APIs.
Also adds a couple of assertions for uncovering any potential issues earlier in 
the constructor; in those cases, the member functions were already 
dereferencing the members unconditionally anyway.

Measurements showed no performance impact, nor crashes.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D126198

Files:
  clang/include/clang/Analysis/AnalysisDeclContext.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
  clang/lib/StaticAnalyzer/Core/MemRegion.cpp

Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ 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; }
 
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ 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;
@@ -535,6 +550,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);
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
+++ 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; }
 };
 
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -360,6 +360,7 @@
     assert(!Loc::isLocType(sym->getType()));
   }
 
+  LLVM_ATTRIBUTE_RETURNS_NONNULL
   SymbolRef getSymbol() const {
     return (const SymExpr *) Data;
   }
@@ -456,9 +457,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<const CompoundValData *>(Data);
   }
@@ -486,14 +490,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<const LazyCompoundValData *>(Data);
   }
 
+  LLVM_ATTRIBUTE_RETURNS_NONNULL
   const void *getStore() const;
+
+  LLVM_ATTRIBUTE_RETURNS_NONNULL
   const TypedValueRegion *getRegion() const;
 
 private:
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -265,6 +265,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;
 
   //==---------------------------------------------------------------------==//
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ 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 migth return null.
   const SymbolicRegion *getSymbolicBase() const;
 
   bool hasGlobalsOrParametersStorage() const;
@@ -169,7 +173,8 @@
   Kind getKind() const { return kind; }
 
   template<typename RegionTy> const RegionTy* getAs() const;
-  template<typename RegionTy> const RegionTy* castAs() const;
+  template <typename RegionTy>
+  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<GlobalImmutableSpaceRegion>(sreg) ||
            isa<StackLocalsSpaceRegion>(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<VarRegion>(*R);
     }
 
+    LLVM_ATTRIBUTE_RETURNS_NONNULL
     const VarRegion *getOriginalRegion() const {
       return cast<VarRegion>(*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<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
            isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(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<StackSpaceRegion>(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<typename RegionTy>
-const RegionTy* MemRegion::castAs() const {
+template <typename RegionTy>
+LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *MemRegion::castAs() const {
   return cast<RegionTy>(this);
 }
 
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h
+++ 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);
 
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -129,6 +129,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;
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ 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<NoteTag>(std::move(Cb), IsPrunable);
   }
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ 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<const CXXBaseSpecifier *> L)
-      : D(D), L(L) {}
+      : D(D), L(L) {
+    assert(D);
+  }
 
   using iterator = llvm::ImmutableList<const CXXBaseSpecifier *>::iterator;
 
@@ -97,6 +103,8 @@
                       llvm::ImmutableList<const CXXBaseSpecifier *> L);
 
   void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, D, L); }
+
+  LLVM_ATTRIBUTE_RETURNS_NONNULL
   const NamedDecl *getDeclaratorDecl() const { return D; }
 
   llvm::ImmutableList<const CXXBaseSpecifier *> getCXXBaseList() const {
Index: clang/include/clang/Analysis/AnalysisDeclContext.h
===================================================================
--- clang/include/clang/Analysis/AnalysisDeclContext.h
+++ 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 migth return null.
   const LocationContext *getParent() const { return Parent; }
 
   bool isParentOf(const LocationContext *LC) const;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to