RedDocMD updated this revision to Diff 319607.
RedDocMD added a comment.

Removing duplication of CXXBaseSpecifiers when they are created for 
PointerToMember
Removed hackish weakening of assert


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95307/new/

https://reviews.llvm.org/D95307

Files:
  clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
  clang/lib/StaticAnalyzer/Core/MemRegion.cpp
  clang/test/Analysis/pointer-to-member.cpp

Index: clang/test/Analysis/pointer-to-member.cpp
===================================================================
--- clang/test/Analysis/pointer-to-member.cpp
+++ clang/test/Analysis/pointer-to-member.cpp
@@ -231,6 +231,23 @@
 }
 } // end of testPointerToMemberDiamond namespace
 
+namespace testPointerToMemberViaStaticCast {
+// From bug #48739
+struct Base {
+  int field;
+};
+
+struct Derived : public Base {};
+
+void static_cast_test() {
+  int Derived::*derived_field = &Derived::field;
+  Base base;
+  base.field = 5;
+  int Base::*base_field = static_cast<int Base::*>(derived_field);
+  clang_analyzer_eval(base.*base_field == 5); // expected-warning {{TRUE}}
+}
+} // namespace testPointerToMemberViaStaticCast
+
 namespace testAnonymousMember {
 struct A {
   int a;
Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -63,7 +63,7 @@
 //===----------------------------------------------------------------------===//
 
 template <typename RegionTy, typename SuperTy, typename Arg1Ty>
-RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1,
+RegionTy *MemRegionManager::getSubRegion(const Arg1Ty arg1,
                                          const SuperTy *superRegion) {
   llvm::FoldingSetNodeID ID;
   RegionTy::ProfileRegion(ID, arg1, superRegion);
@@ -80,7 +80,7 @@
 }
 
 template <typename RegionTy, typename SuperTy, typename Arg1Ty, typename Arg2Ty>
-RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
+RegionTy *MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
                                          const SuperTy *superRegion) {
   llvm::FoldingSetNodeID ID;
   RegionTy::ProfileRegion(ID, arg1, arg2, superRegion);
@@ -96,9 +96,9 @@
   return R;
 }
 
-template <typename RegionTy, typename SuperTy,
-          typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
-RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
+template <typename RegionTy, typename SuperTy, typename Arg1Ty, typename Arg2Ty,
+          typename Arg3Ty>
+RegionTy *MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
                                          const Arg3Ty arg3,
                                          const SuperTy *superRegion) {
   llvm::FoldingSetNodeID ID;
@@ -129,8 +129,8 @@
 // Basic methods.
 //===----------------------------------------------------------------------===//
 
-bool SubRegion::isSubRegionOf(const MemRegion* R) const {
-  const MemRegion* r = this;
+bool SubRegion::isSubRegionOf(const MemRegion *R) const {
+  const MemRegion *r = this;
   do {
     if (r == R)
       return true;
@@ -143,7 +143,7 @@
 }
 
 MemRegionManager &SubRegion::getMemRegionManager() const {
-  const SubRegion* r = this;
+  const SubRegion *r = this;
   do {
     const MemRegion *superRegion = r->getSuperRegion();
     if (const auto *sr = dyn_cast<SubRegion>(superRegion)) {
@@ -164,9 +164,7 @@
 
 const ObjCIvarDecl *ObjCIvarRegion::getDecl() const { return IVD; }
 
-QualType ObjCIvarRegion::getValueType() const {
-  return getDecl()->getType();
-}
+QualType ObjCIvarRegion::getValueType() const { return getDecl()->getType(); }
 
 QualType CXXBaseObjectRegion::getValueType() const {
   return QualType(getDecl()->getTypeForDecl(), 0);
@@ -237,26 +235,25 @@
   ID.AddPointer(superRegion);
 }
 
-void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
-                                 const Expr *Ex, unsigned cnt,
-                                 const MemRegion *superRegion) {
+void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *Ex,
+                                 unsigned cnt, const MemRegion *superRegion) {
   ID.AddInteger(static_cast<unsigned>(AllocaRegionKind));
   ID.AddPointer(Ex);
   ID.AddInteger(cnt);
   ID.AddPointer(superRegion);
 }
 
-void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+void AllocaRegion::Profile(llvm::FoldingSetNodeID &ID) const {
   ProfileRegion(ID, Ex, Cnt, superRegion);
 }
 
-void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID &ID) const {
   CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
 }
 
-void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                           const CompoundLiteralExpr *CL,
-                                          const MemRegion* superRegion) {
+                                          const MemRegion *superRegion) {
   ID.AddInteger(static_cast<unsigned>(CompoundLiteralRegionKind));
   ID.AddPointer(CL);
   ID.AddPointer(superRegion);
@@ -278,9 +275,9 @@
   ProfileRegion(ID, getDecl(), superRegion);
 }
 
-void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                    const ObjCIvarDecl *ivd,
-                                   const MemRegion* superRegion) {
+                                   const MemRegion *superRegion) {
   ID.AddInteger(static_cast<unsigned>(ObjCIvarRegionKind));
   ID.AddPointer(ivd);
   ID.AddPointer(superRegion);
@@ -314,58 +311,56 @@
   ProfileRegion(ID, getOriginExpr(), getIndex(), superRegion);
 }
 
-void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
+void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, SymbolRef sym,
                                    const MemRegion *sreg) {
   ID.AddInteger(static_cast<unsigned>(MemRegion::SymbolicRegionKind));
   ID.Add(sym);
   ID.AddPointer(sreg);
 }
 
-void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+void SymbolicRegion::Profile(llvm::FoldingSetNodeID &ID) const {
   SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
 }
 
-void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                   QualType ElementType, SVal Idx,
-                                  const MemRegion* superRegion) {
+                                  const MemRegion *superRegion) {
   ID.AddInteger(MemRegion::ElementRegionKind);
   ID.Add(ElementType);
   ID.AddPointer(superRegion);
   Idx.Profile(ID);
 }
 
-void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+void ElementRegion::Profile(llvm::FoldingSetNodeID &ID) const {
   ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
 }
 
-void FunctionCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
-                                       const NamedDecl *FD,
-                                       const MemRegion*) {
+void FunctionCodeRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
+                                       const NamedDecl *FD, const MemRegion *) {
   ID.AddInteger(MemRegion::FunctionCodeRegionKind);
   ID.AddPointer(FD);
 }
 
-void FunctionCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+void FunctionCodeRegion::Profile(llvm::FoldingSetNodeID &ID) const {
   FunctionCodeRegion::ProfileRegion(ID, FD, superRegion);
 }
 
-void BlockCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+void BlockCodeRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                     const BlockDecl *BD, CanQualType,
                                     const AnalysisDeclContext *AC,
-                                    const MemRegion*) {
+                                    const MemRegion *) {
   ID.AddInteger(MemRegion::BlockCodeRegionKind);
   ID.AddPointer(BD);
 }
 
-void BlockCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+void BlockCodeRegion::Profile(llvm::FoldingSetNodeID &ID) const {
   BlockCodeRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
 }
 
-void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                     const BlockCodeRegion *BC,
                                     const LocationContext *LC,
-                                    unsigned BlkCount,
-                                    const MemRegion *sReg) {
+                                    unsigned BlkCount, const MemRegion *sReg) {
   ID.AddInteger(MemRegion::BlockDataRegionKind);
   ID.AddPointer(BC);
   ID.AddPointer(LC);
@@ -373,13 +368,12 @@
   ID.AddPointer(sReg);
 }
 
-void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+void BlockDataRegion::Profile(llvm::FoldingSetNodeID &ID) const {
   BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion());
 }
 
 void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
-                                        Expr const *Ex,
-                                        const MemRegion *sReg) {
+                                        Expr const *Ex, const MemRegion *sReg) {
   ID.AddPointer(Ex);
   ID.AddPointer(sReg);
 }
@@ -389,8 +383,7 @@
 }
 
 void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
-                                        const CXXRecordDecl *RD,
-                                        bool IsVirtual,
+                                        const CXXRecordDecl *RD, bool IsVirtual,
                                         const MemRegion *SReg) {
   ID.AddPointer(RD);
   ID.AddBoolean(IsVirtual);
@@ -434,9 +427,7 @@
 // Region pretty-printing.
 //===----------------------------------------------------------------------===//
 
-LLVM_DUMP_METHOD void MemRegion::dump() const {
-  dumpToStream(llvm::errs());
-}
+LLVM_DUMP_METHOD void MemRegion::dump() const { dumpToStream(llvm::errs()); }
 
 std::string MemRegion::getString() const {
   std::string s;
@@ -464,17 +455,16 @@
 void BlockDataRegion::dumpToStream(raw_ostream &os) const {
   os << "block_data{" << BC;
   os << "; ";
-  for (BlockDataRegion::referenced_vars_iterator
-         I = referenced_vars_begin(),
-         E = referenced_vars_end(); I != E; ++I)
-    os << "(" << I.getCapturedRegion() << "<-" <<
-                 I.getOriginalRegion() << ") ";
+  for (BlockDataRegion::referenced_vars_iterator I = referenced_vars_begin(),
+                                                 E = referenced_vars_end();
+       I != E; ++I)
+    os << "(" << I.getCapturedRegion() << "<-" << I.getOriginalRegion() << ") ";
   os << '}';
 }
 
 void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
   // FIXME: More elaborate pretty-printing.
-  os << "{ S" << CL->getID(getContext()) <<  " }";
+  os << "{ S" << CL->getID(getContext()) << " }";
 }
 
 void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
@@ -490,13 +480,11 @@
   os << "Derived{" << superRegion << ',' << getDecl()->getName() << '}';
 }
 
-void CXXThisRegion::dumpToStream(raw_ostream &os) const {
-  os << "this";
-}
+void CXXThisRegion::dumpToStream(raw_ostream &os) const { os << "this"; }
 
 void ElementRegion::dumpToStream(raw_ostream &os) const {
-  os << "Element{" << superRegion << ','
-     << Index << ',' << getElementType().getAsString() << '}';
+  os << "Element{" << superRegion << ',' << Index << ','
+     << getElementType().getAsString() << '}';
 }
 
 void FieldRegion::dumpToStream(raw_ostream &os) const {
@@ -586,13 +574,9 @@
   }
 }
 
-bool MemRegion::canPrintPretty() const {
-  return canPrintPrettyAsExpr();
-}
+bool MemRegion::canPrintPretty() const { return canPrintPrettyAsExpr(); }
 
-bool MemRegion::canPrintPrettyAsExpr() const {
-  return false;
-}
+bool MemRegion::canPrintPrettyAsExpr() const { return false; }
 
 void MemRegion::printPretty(raw_ostream &os) const {
   assert(canPrintPretty() && "This region cannot be printed pretty.");
@@ -620,17 +604,13 @@
   os << getDecl()->getName();
 }
 
-bool ObjCIvarRegion::canPrintPrettyAsExpr() const {
-  return true;
-}
+bool ObjCIvarRegion::canPrintPrettyAsExpr() const { return true; }
 
 void ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const {
   os << getDecl()->getName();
 }
 
-bool FieldRegion::canPrintPretty() const {
-  return true;
-}
+bool FieldRegion::canPrintPretty() const { return true; }
 
 bool FieldRegion::canPrintPrettyAsExpr() const {
   return superRegion->canPrintPrettyAsExpr();
@@ -648,7 +628,8 @@
     printPrettyAsExpr(os);
     os << "'";
   } else {
-    os << "field " << "\'" << getDecl()->getName() << "'";
+    os << "field "
+       << "\'" << getDecl()->getName() << "'";
   }
 }
 
@@ -730,7 +711,7 @@
 //===----------------------------------------------------------------------===//
 
 static DefinedOrUnknownSVal getTypeSize(QualType Ty, ASTContext &Ctx,
-                                          SValBuilder &SVB) {
+                                        SValBuilder &SVB) {
   CharUnits Size = Ctx.getTypeSizeInChars(Ty);
   QualType SizeTy = SVB.getArrayIndexType();
   return SVB.makeIntVal(Size.getQuantity(), SizeTy);
@@ -798,7 +779,7 @@
 }
 
 template <typename REG>
-const REG *MemRegionManager::LazyAllocate(REG*& region) {
+const REG *MemRegionManager::LazyAllocate(REG *&region) {
   if (!region) {
     region = A.Allocate<REG>();
     new (region) REG(*this);
@@ -808,7 +789,7 @@
 }
 
 template <typename REG, typename ARG>
-const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
+const REG *MemRegionManager::LazyAllocate(REG *&region, ARG a) {
   if (!region) {
     region = A.Allocate<REG>();
     new (region) REG(this, a);
@@ -817,7 +798,7 @@
   return region;
 }
 
-const StackLocalsSpaceRegion*
+const StackLocalsSpaceRegion *
 MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
   assert(STC);
   StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
@@ -843,9 +824,9 @@
   return R;
 }
 
-const GlobalsSpaceRegion
-*MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
-                                    const CodeTextRegion *CR) {
+const GlobalsSpaceRegion *
+MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
+                                   const CodeTextRegion *CR) {
   if (!CR) {
     if (K == MemRegion::GlobalSystemSpaceRegionKind)
       return LazyAllocate(SystemGlobals);
@@ -881,13 +862,14 @@
 // Constructing regions.
 //===----------------------------------------------------------------------===//
 
-const StringRegion *MemRegionManager::getStringRegion(const StringLiteral *Str){
+const StringRegion *
+MemRegionManager::getStringRegion(const StringLiteral *Str) {
   return getSubRegion<StringRegion>(
       Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
 }
 
 const ObjCStringRegion *
-MemRegionManager::getObjCStringRegion(const ObjCStringLiteral *Str){
+MemRegionManager::getObjCStringRegion(const ObjCStringLiteral *Str) {
   return getSubRegion<ObjCStringRegion>(
       Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
 }
@@ -908,8 +890,9 @@
       const auto *BR = static_cast<const BlockDataRegion *>(BC->getData());
       // FIXME: This can be made more efficient.
       for (BlockDataRegion::referenced_vars_iterator
-           I = BR->referenced_vars_begin(),
-           E = BR->referenced_vars_end(); I != E; ++I) {
+               I = BR->referenced_vars_begin(),
+               E = BR->referenced_vars_end();
+           I != E; ++I) {
         const TypedValueRegion *OrigR = I.getOriginalRegion();
         if (const auto *VR = dyn_cast<VarRegion>(OrigR)) {
           if (VR->getDecl() == VD)
@@ -961,7 +944,7 @@
       else
         sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
 
-    // Treat other globals as GlobalInternal unless they are constants.
+      // Treat other globals as GlobalInternal unless they are constants.
     } else {
       QualType GQT = D->getType();
       const Type *GT = GQT.getTypePtrOrNull();
@@ -973,16 +956,16 @@
         sReg = getGlobalsRegion();
     }
 
-  // Finally handle static locals.
+    // Finally handle static locals.
   } else {
     // FIXME: Once we implement scope handling, we will need to properly lookup
     // 'D' to the proper LocationContext.
     const DeclContext *DC = D->getDeclContext();
     llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
-      getStackOrCaptureRegionForDeclContext(LC, DC, D);
+        getStackOrCaptureRegionForDeclContext(LC, DC, D);
 
-    if (V.is<const VarRegion*>())
-      return V.get<const VarRegion*>();
+    if (V.is<const VarRegion *>())
+      return V.get<const VarRegion *>();
 
     const auto *STC = V.get<const StackFrameContext *>();
 
@@ -992,11 +975,11 @@
       sReg = getUnknownRegion();
     } else {
       if (D->hasLocalStorage()) {
-        sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
-               ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
-               : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
-      }
-      else {
+        sReg =
+            isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
+                ? static_cast<const MemRegion *>(getStackArgumentsRegion(STC))
+                : static_cast<const MemRegion *>(getStackLocalsRegion(STC));
+      } else {
         assert(D->isStaticLocal());
         const Decl *STCD = STC->getDecl();
         if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
@@ -1016,13 +999,10 @@
             T = getContext().getFunctionNoProtoType(T);
           T = getContext().getBlockPointerType(T);
 
-          const BlockCodeRegion *BTR =
-            getBlockCodeRegion(BD, Ctx.getCanonicalType(T),
-                               STC->getAnalysisDeclContext());
-          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
-                                  BTR);
-        }
-        else {
+          const BlockCodeRegion *BTR = getBlockCodeRegion(
+              BD, Ctx.getCanonicalType(T), STC->getAnalysisDeclContext());
+          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, BTR);
+        } else {
           sReg = getGlobalsRegion();
         }
       }
@@ -1048,25 +1028,21 @@
                                       getStackArgumentsRegion(SFC));
 }
 
-const BlockDataRegion *
-MemRegionManager::getBlockDataRegion(const BlockCodeRegion *BC,
-                                     const LocationContext *LC,
-                                     unsigned blockCount) {
+const BlockDataRegion *MemRegionManager::getBlockDataRegion(
+    const BlockCodeRegion *BC, const LocationContext *LC, unsigned blockCount) {
   const MemSpaceRegion *sReg = nullptr;
   const BlockDecl *BD = BC->getDecl();
   if (!BD->hasCaptures()) {
     // This handles 'static' blocks.
     sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
-  }
-  else {
+  } else {
     if (LC) {
       // FIXME: Once we implement scope handling, we want the parent region
       // to be the scope.
       const StackFrameContext *STC = LC->getStackFrame();
       assert(STC);
       sReg = getStackLocalsRegion(STC);
-    }
-    else {
+    } else {
       // We allow 'LC' to be NULL for cases where want BlockDataRegions
       // without context-sensitivity.
       sReg = getUnknownRegion();
@@ -1082,7 +1058,7 @@
       Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, nullptr));
 }
 
-const CompoundLiteralRegion*
+const CompoundLiteralRegion *
 MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
                                            const LocationContext *LC) {
   const MemSpaceRegion *sReg = nullptr;
@@ -1098,17 +1074,17 @@
   return getSubRegion<CompoundLiteralRegion>(CL, sReg);
 }
 
-const ElementRegion*
+const ElementRegion *
 MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
-                                   const SubRegion* superRegion,
-                                   ASTContext &Ctx){
+                                   const SubRegion *superRegion,
+                                   ASTContext &Ctx) {
   QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
 
   llvm::FoldingSetNodeID ID;
   ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
 
   void *InsertPos;
-  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
+  MemRegion *data = Regions.FindNodeOrInsertPos(ID, InsertPos);
   auto *R = cast_or_null<ElementRegion>(data);
 
   if (!R) {
@@ -1141,19 +1117,19 @@
   return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
 }
 
-const FieldRegion*
+const FieldRegion *
 MemRegionManager::getFieldRegion(const FieldDecl *d,
-                                 const SubRegion* superRegion){
+                                 const SubRegion *superRegion) {
   return getSubRegion<FieldRegion>(d, superRegion);
 }
 
-const ObjCIvarRegion*
+const ObjCIvarRegion *
 MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
-                                    const SubRegion* superRegion) {
+                                    const SubRegion *superRegion) {
   return getSubRegion<ObjCIvarRegion>(d, superRegion);
 }
 
-const CXXTempObjectRegion*
+const CXXTempObjectRegion *
 MemRegionManager::getCXXTempObjectRegion(Expr const *E,
                                          LocationContext const *LC) {
   const StackFrameContext *SFC = LC->getStackFrame();
@@ -1164,8 +1140,7 @@
 /// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
 /// class of the type of \p Super.
 static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
-                             const TypedValueRegion *Super,
-                             bool IsVirtual) {
+                             const TypedValueRegion *Super, bool IsVirtual) {
   BaseClass = BaseClass->getCanonicalDecl();
 
   const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl();
@@ -1183,10 +1158,8 @@
   return false;
 }
 
-const CXXBaseObjectRegion *
-MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
-                                         const SubRegion *Super,
-                                         bool IsVirtual) {
+const CXXBaseObjectRegion *MemRegionManager::getCXXBaseObjectRegion(
+    const CXXRecordDecl *RD, const SubRegion *Super, bool IsVirtual) {
   if (isa<TypedValueRegion>(Super)) {
     assert(isValidBaseClass(RD, cast<TypedValueRegion>(Super), IsVirtual));
     (void)&isValidBaseClass;
@@ -1209,7 +1182,7 @@
   return getSubRegion<CXXDerivedObjectRegion>(RD, Super);
 }
 
-const CXXThisRegion*
+const CXXThisRegion *
 MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
                                    const LocationContext *LC) {
   const auto *PT = thisPointerTy->getAs<PointerType>();
@@ -1230,7 +1203,7 @@
   return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
 }
 
-const AllocaRegion*
+const AllocaRegion *
 MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt,
                                   const LocationContext *LC) {
   const StackFrameContext *STC = LC->getStackFrame();
@@ -1264,8 +1237,7 @@
 
 bool MemRegion::hasGlobalsOrParametersStorage() const {
   const MemSpaceRegion *MS = getMemorySpace();
-  return isa<StackArgumentsSpaceRegion>(MS) ||
-         isa<GlobalsSpaceRegion>(MS);
+  return isa<StackArgumentsSpaceRegion>(MS) || isa<GlobalsSpaceRegion>(MS);
 }
 
 // getBaseRegion strips away all elements and fields, and get the base region
@@ -1274,15 +1246,15 @@
   const MemRegion *R = this;
   while (true) {
     switch (R->getKind()) {
-      case MemRegion::ElementRegionKind:
-      case MemRegion::FieldRegionKind:
-      case MemRegion::ObjCIvarRegionKind:
-      case MemRegion::CXXBaseObjectRegionKind:
-      case MemRegion::CXXDerivedObjectRegionKind:
-        R = cast<SubRegion>(R)->getSuperRegion();
-        continue;
-      default:
-        break;
+    case MemRegion::ElementRegionKind:
+    case MemRegion::FieldRegionKind:
+    case MemRegion::ObjCIvarRegionKind:
+    case MemRegion::CXXBaseObjectRegionKind:
+    case MemRegion::CXXDerivedObjectRegionKind:
+      R = cast<SubRegion>(R)->getSuperRegion();
+      continue;
+    default:
+      break;
     }
     break;
   }
@@ -1298,9 +1270,7 @@
   return R;
 }
 
-bool MemRegion::isSubRegionOf(const MemRegion *) const {
-  return false;
-}
+bool MemRegion::isSubRegionOf(const MemRegion *) const { return false; }
 
 //===----------------------------------------------------------------------===//
 // View handling.
@@ -1560,7 +1530,8 @@
       // Get the field number.
       unsigned idx = 0;
       for (RecordDecl::field_iterator FI = RD->field_begin(),
-             FE = RD->field_end(); FI != FE; ++FI, ++idx) {
+                                      FE = RD->field_end();
+           FI != FE; ++FI, ++idx) {
         if (FR->getDecl() == *FI)
           break;
       }
@@ -1572,7 +1543,7 @@
     }
   }
 
- Finish:
+Finish:
   if (SymbolicOffsetBase)
     return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
   return RegionOffset(R, Offset);
@@ -1597,13 +1568,11 @@
   if (!VD->hasAttr<BlocksAttr>() && VD->hasLocalStorage()) {
     VR = MemMgr.getNonParamVarRegion(VD, this);
     OriginalVR = MemMgr.getVarRegion(VD, LC);
-  }
-  else {
+  } else {
     if (LC) {
       VR = MemMgr.getVarRegion(VD, LC);
       OriginalVR = VR;
-    }
-    else {
+    } else {
       VR = MemMgr.getNonParamVarRegion(VD, MemMgr.getUnknownRegion());
       OriginalVR = MemMgr.getVarRegion(VD, LC);
     }
@@ -1621,7 +1590,7 @@
       std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
 
   if (NumBlockVars == 0) {
-    ReferencedVars = (void*) 0x1;
+    ReferencedVars = (void *)0x1;
     return;
   }
 
@@ -1652,11 +1621,11 @@
 
 BlockDataRegion::referenced_vars_iterator
 BlockDataRegion::referenced_vars_begin() const {
-  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
+  const_cast<BlockDataRegion *>(this)->LazyInitializeReferencedVars();
 
   auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars);
 
-  if (Vec == (void*) 0x1)
+  if (Vec == (void *)0x1)
     return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
 
   auto *VecOriginal =
@@ -1668,11 +1637,11 @@
 
 BlockDataRegion::referenced_vars_iterator
 BlockDataRegion::referenced_vars_end() const {
-  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
+  const_cast<BlockDataRegion *>(this)->LazyInitializeReferencedVars();
 
   auto *Vec = static_cast<BumpVector<const MemRegion *> *>(ReferencedVars);
 
-  if (Vec == (void*) 0x1)
+  if (Vec == (void *)0x1)
     return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
 
   auto *VecOriginal =
Index: clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
+++ clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
@@ -21,6 +21,7 @@
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/ImmutableList.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include <cassert>
 #include <cstdint>
 #include <utility>
@@ -28,13 +29,13 @@
 using namespace clang;
 using namespace ento;
 
-void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
+void CompoundValData::Profile(llvm::FoldingSetNodeID &ID, QualType T,
                               llvm::ImmutableList<SVal> L) {
   T.Profile(ID);
   ID.AddPointer(L.getInternalPointer());
 }
 
-void LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID,
+void LazyCompoundValData::Profile(llvm::FoldingSetNodeID &ID,
                                   const StoreRef &store,
                                   const TypedValueRegion *region) {
   ID.AddPointer(store.getStore());
@@ -53,15 +54,15 @@
 
 namespace llvm {
 
-template<> struct FoldingSetTrait<SValData> {
-  static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
+template <> struct FoldingSetTrait<SValData> {
+  static inline void Profile(const SValData &X, llvm::FoldingSetNodeID &ID) {
     X.first.Profile(ID);
-    ID.AddPointer( (void*) X.second);
+    ID.AddPointer((void *)X.second);
   }
 };
 
-template<> struct FoldingSetTrait<SValPair> {
-  static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) {
+template <> struct FoldingSetTrait<SValPair> {
+  static inline void Profile(const SValPair &X, llvm::FoldingSetNodeID &ID) {
     X.first.Profile(ID);
     X.second.Profile(ID);
   }
@@ -82,21 +83,21 @@
   for (const auto &I : APSIntSet)
     I.getValue().~APSInt();
 
-  delete (PersistentSValsTy*) PersistentSVals;
-  delete (PersistentSValPairsTy*) PersistentSValPairs;
+  delete (PersistentSValsTy *)PersistentSVals;
+  delete (PersistentSValPairsTy *)PersistentSValPairs;
 }
 
-const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
+const llvm::APSInt &BasicValueFactory::getValue(const llvm::APSInt &X) {
   llvm::FoldingSetNodeID ID;
   void *InsertPos;
 
   using FoldNodeTy = llvm::FoldingSetNodeWrapper<llvm::APSInt>;
 
   X.Profile(ID);
-  FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
+  FoldNodeTy *P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
 
   if (!P) {
-    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
+    P = (FoldNodeTy *)BPAlloc.Allocate<FoldNodeTy>();
     new (P) FoldNodeTy(X);
     APSIntSet.InsertNode(P, InsertPos);
   }
@@ -104,34 +105,34 @@
   return *P;
 }
 
-const llvm::APSInt& BasicValueFactory::getValue(const llvm::APInt& X,
+const llvm::APSInt &BasicValueFactory::getValue(const llvm::APInt &X,
                                                 bool isUnsigned) {
   llvm::APSInt V(X, isUnsigned);
   return getValue(V);
 }
 
-const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
-                                           bool isUnsigned) {
+const llvm::APSInt &BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
+                                                bool isUnsigned) {
   llvm::APSInt V(BitWidth, isUnsigned);
   V = X;
   return getValue(V);
 }
 
-const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
+const llvm::APSInt &BasicValueFactory::getValue(uint64_t X, QualType T) {
   return getValue(getAPSIntType(T).getValue(X));
 }
 
-const CompoundValData*
+const CompoundValData *
 BasicValueFactory::getCompoundValData(QualType T,
                                       llvm::ImmutableList<SVal> Vals) {
   llvm::FoldingSetNodeID ID;
   CompoundValData::Profile(ID, T, Vals);
   void *InsertPos;
 
-  CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
+  CompoundValData *D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
 
   if (!D) {
-    D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
+    D = (CompoundValData *)BPAlloc.Allocate<CompoundValData>();
     new (D) CompoundValData(T, Vals);
     CompoundValDataSet.InsertNode(D, InsertPos);
   }
@@ -139,7 +140,7 @@
   return D;
 }
 
-const LazyCompoundValData*
+const LazyCompoundValData *
 BasicValueFactory::getLazyCompoundValData(const StoreRef &store,
                                           const TypedValueRegion *region) {
   llvm::FoldingSetNodeID ID;
@@ -147,10 +148,10 @@
   void *InsertPos;
 
   LazyCompoundValData *D =
-    LazyCompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
+      LazyCompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
 
   if (!D) {
-    D = (LazyCompoundValData*) BPAlloc.Allocate<LazyCompoundValData>();
+    D = (LazyCompoundValData *)BPAlloc.Allocate<LazyCompoundValData>();
     new (D) LazyCompoundValData(store, region);
     LazyCompoundValDataSet.InsertNode(D, InsertPos);
   }
@@ -195,124 +196,134 @@
     PathList = PTMD->getCXXBaseList();
   }
 
-  for (const auto &I : llvm::reverse(PathRange))
-    PathList = prependCXXBase(I, PathList);
+  llvm::SmallPtrSet<QualType, 32> BaseTypes;
+  for (const auto &BaseSpec : PathList)
+    BaseTypes.insert(BaseSpec->getType());
+
+  for (const auto &I : llvm::reverse(PathRange)) {
+    auto IType = I->getType();
+    if (!BaseTypes.contains(IType)) {
+      PathList = prependCXXBase(I, PathList);
+      BaseTypes.insert(IType);
+    }
+  }
   return getPointerToMemberData(ND, PathList);
 }
 
-const llvm::APSInt*
-BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
-                             const llvm::APSInt& V1, const llvm::APSInt& V2) {
+const llvm::APSInt *BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
+                                                  const llvm::APSInt &V1,
+                                                  const llvm::APSInt &V2) {
   switch (Op) {
-    default:
-      llvm_unreachable("Invalid Opcode.");
+  default:
+    llvm_unreachable("Invalid Opcode.");
 
-    case BO_Mul:
-      return &getValue( V1 * V2 );
+  case BO_Mul:
+    return &getValue(V1 * V2);
 
-    case BO_Div:
-      if (V2 == 0) // Avoid division by zero
-        return nullptr;
-      return &getValue( V1 / V2 );
+  case BO_Div:
+    if (V2 == 0) // Avoid division by zero
+      return nullptr;
+    return &getValue(V1 / V2);
 
-    case BO_Rem:
-      if (V2 == 0) // Avoid division by zero
-        return nullptr;
-      return &getValue( V1 % V2 );
-
-    case BO_Add:
-      return &getValue( V1 + V2 );
+  case BO_Rem:
+    if (V2 == 0) // Avoid division by zero
+      return nullptr;
+    return &getValue(V1 % V2);
 
-    case BO_Sub:
-      return &getValue( V1 - V2 );
+  case BO_Add:
+    return &getValue(V1 + V2);
 
-    case BO_Shl: {
-      // FIXME: This logic should probably go higher up, where we can
-      // test these conditions symbolically.
+  case BO_Sub:
+    return &getValue(V1 - V2);
 
-      if (V2.isSigned() && V2.isNegative())
-        return nullptr;
+  case BO_Shl: {
+    // FIXME: This logic should probably go higher up, where we can
+    // test these conditions symbolically.
 
-      uint64_t Amt = V2.getZExtValue();
+    if (V2.isSigned() && V2.isNegative())
+      return nullptr;
 
-      if (Amt >= V1.getBitWidth())
-        return nullptr;
+    uint64_t Amt = V2.getZExtValue();
 
-      if (!Ctx.getLangOpts().CPlusPlus20) {
-        if (V1.isSigned() && V1.isNegative())
-          return nullptr;
+    if (Amt >= V1.getBitWidth())
+      return nullptr;
 
-        if (V1.isSigned() && Amt > V1.countLeadingZeros())
-          return nullptr;
-      }
+    if (!Ctx.getLangOpts().CPlusPlus20) {
+      if (V1.isSigned() && V1.isNegative())
+        return nullptr;
 
-      return &getValue( V1.operator<<( (unsigned) Amt ));
+      if (V1.isSigned() && Amt > V1.countLeadingZeros())
+        return nullptr;
     }
 
-    case BO_Shr: {
-      // FIXME: This logic should probably go higher up, where we can
-      // test these conditions symbolically.
+    return &getValue(V1.operator<<((unsigned)Amt));
+  }
 
-      if (V2.isSigned() && V2.isNegative())
-        return nullptr;
+  case BO_Shr: {
+    // FIXME: This logic should probably go higher up, where we can
+    // test these conditions symbolically.
 
-      uint64_t Amt = V2.getZExtValue();
+    if (V2.isSigned() && V2.isNegative())
+      return nullptr;
 
-      if (Amt >= V1.getBitWidth())
-        return nullptr;
+    uint64_t Amt = V2.getZExtValue();
 
-      return &getValue( V1.operator>>( (unsigned) Amt ));
-    }
+    if (Amt >= V1.getBitWidth())
+      return nullptr;
+
+    return &getValue(V1.operator>>((unsigned)Amt));
+  }
 
-    case BO_LT:
-      return &getTruthValue( V1 < V2 );
+  case BO_LT:
+    return &getTruthValue(V1 < V2);
 
-    case BO_GT:
-      return &getTruthValue( V1 > V2 );
+  case BO_GT:
+    return &getTruthValue(V1 > V2);
 
-    case BO_LE:
-      return &getTruthValue( V1 <= V2 );
+  case BO_LE:
+    return &getTruthValue(V1 <= V2);
 
-    case BO_GE:
-      return &getTruthValue( V1 >= V2 );
+  case BO_GE:
+    return &getTruthValue(V1 >= V2);
 
-    case BO_EQ:
-      return &getTruthValue( V1 == V2 );
+  case BO_EQ:
+    return &getTruthValue(V1 == V2);
 
-    case BO_NE:
-      return &getTruthValue( V1 != V2 );
+  case BO_NE:
+    return &getTruthValue(V1 != V2);
 
-      // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
+    // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
 
-    case BO_And:
-      return &getValue( V1 & V2 );
+  case BO_And:
+    return &getValue(V1 & V2);
 
-    case BO_Or:
-      return &getValue( V1 | V2 );
+  case BO_Or:
+    return &getValue(V1 | V2);
 
-    case BO_Xor:
-      return &getValue( V1 ^ V2 );
+  case BO_Xor:
+    return &getValue(V1 ^ V2);
   }
 }
 
-const std::pair<SVal, uintptr_t>&
-BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
+const std::pair<SVal, uintptr_t> &
+BasicValueFactory::getPersistentSValWithData(const SVal &V, uintptr_t Data) {
   // Lazily create the folding set.
-  if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
+  if (!PersistentSVals)
+    PersistentSVals = new PersistentSValsTy();
 
   llvm::FoldingSetNodeID ID;
   void *InsertPos;
   V.Profile(ID);
-  ID.AddPointer((void*) Data);
+  ID.AddPointer((void *)Data);
 
-  PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
+  PersistentSValsTy &Map = *((PersistentSValsTy *)PersistentSVals);
 
   using FoldNodeTy = llvm::FoldingSetNodeWrapper<SValData>;
 
-  FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
+  FoldNodeTy *P = Map.FindNodeOrInsertPos(ID, InsertPos);
 
   if (!P) {
-    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
+    P = (FoldNodeTy *)BPAlloc.Allocate<FoldNodeTy>();
     new (P) FoldNodeTy(std::make_pair(V, Data));
     Map.InsertNode(P, InsertPos);
   }
@@ -320,24 +331,25 @@
   return P->getValue();
 }
 
-const std::pair<SVal, SVal>&
-BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
+const std::pair<SVal, SVal> &
+BasicValueFactory::getPersistentSValPair(const SVal &V1, const SVal &V2) {
   // Lazily create the folding set.
-  if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
+  if (!PersistentSValPairs)
+    PersistentSValPairs = new PersistentSValPairsTy();
 
   llvm::FoldingSetNodeID ID;
   void *InsertPos;
   V1.Profile(ID);
   V2.Profile(ID);
 
-  PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
+  PersistentSValPairsTy &Map = *((PersistentSValPairsTy *)PersistentSValPairs);
 
   using FoldNodeTy = llvm::FoldingSetNodeWrapper<SValPair>;
 
-  FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
+  FoldNodeTy *P = Map.FindNodeOrInsertPos(ID, InsertPos);
 
   if (!P) {
-    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
+    P = (FoldNodeTy *)BPAlloc.Allocate<FoldNodeTy>();
     new (P) FoldNodeTy(std::make_pair(V1, V2));
     Map.InsertNode(P, InsertPos);
   }
@@ -345,6 +357,6 @@
   return P->getValue();
 }
 
-const SVal* BasicValueFactory::getPersistentSVal(SVal X) {
+const SVal *BasicValueFactory::getPersistentSVal(SVal X) {
   return &getPersistentSValWithData(X, 0).first;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to