diff --git a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp --- a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp +++ b/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 #include #include @@ -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 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 { - static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) { +template <> struct FoldingSetTrait { + 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 { - static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) { +template <> struct FoldingSetTrait { + 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; X.Profile(ID); - FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos); + FoldNodeTy *P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos); if (!P) { - P = (FoldNodeTy*) BPAlloc.Allocate(); + P = (FoldNodeTy *)BPAlloc.Allocate(); 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 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(); + D = (CompoundValData *)BPAlloc.Allocate(); 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(); + D = (LazyCompoundValData *)BPAlloc.Allocate(); 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 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& -BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) { +const std::pair & +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; - FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos); + FoldNodeTy *P = Map.FindNodeOrInsertPos(ID, InsertPos); if (!P) { - P = (FoldNodeTy*) BPAlloc.Allocate(); + P = (FoldNodeTy *)BPAlloc.Allocate(); new (P) FoldNodeTy(std::make_pair(V, Data)); Map.InsertNode(P, InsertPos); } @@ -320,24 +331,25 @@ return P->getValue(); } -const std::pair& -BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) { +const std::pair & +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; - FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos); + FoldNodeTy *P = Map.FindNodeOrInsertPos(ID, InsertPos); if (!P) { - P = (FoldNodeTy*) BPAlloc.Allocate(); + P = (FoldNodeTy *)BPAlloc.Allocate(); 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; } 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 @@ -63,7 +63,7 @@ //===----------------------------------------------------------------------===// template -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 -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 -RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2, +template +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(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(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(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(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(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 -const REG *MemRegionManager::LazyAllocate(REG*& region) { +const REG *MemRegionManager::LazyAllocate(REG *®ion) { if (!region) { region = A.Allocate(); new (region) REG(*this); @@ -808,7 +789,7 @@ } template -const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) { +const REG *MemRegionManager::LazyAllocate(REG *®ion, ARG a) { if (!region) { region = A.Allocate(); 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( Str, cast(getGlobalsRegion())); } const ObjCStringRegion * -MemRegionManager::getObjCStringRegion(const ObjCStringLiteral *Str){ +MemRegionManager::getObjCStringRegion(const ObjCStringLiteral *Str) { return getSubRegion( Str, cast(getGlobalsRegion())); } @@ -908,8 +890,9 @@ const auto *BR = static_cast(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(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 V = - getStackOrCaptureRegionForDeclContext(LC, DC, D); + getStackOrCaptureRegionForDeclContext(LC, DC, D); - if (V.is()) - return V.get(); + if (V.is()) + return V.get(); const auto *STC = V.get(); @@ -992,11 +975,11 @@ sReg = getUnknownRegion(); } else { if (D->hasLocalStorage()) { - sReg = isa(D) || isa(D) - ? static_cast(getStackArgumentsRegion(STC)) - : static_cast(getStackLocalsRegion(STC)); - } - else { + sReg = + isa(D) || isa(D) + ? static_cast(getStackArgumentsRegion(STC)) + : static_cast(getStackLocalsRegion(STC)); + } else { assert(D->isStaticLocal()); const Decl *STCD = STC->getDecl(); if (isa(STCD) || isa(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(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(data); if (!R) { @@ -1141,19 +1117,19 @@ return getSubRegion(Sym, getHeapRegion()); } -const FieldRegion* +const FieldRegion * MemRegionManager::getFieldRegion(const FieldDecl *d, - const SubRegion* superRegion){ + const SubRegion *superRegion) { return getSubRegion(d, superRegion); } -const ObjCIvarRegion* +const ObjCIvarRegion * MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d, - const SubRegion* superRegion) { + const SubRegion *superRegion) { return getSubRegion(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(Super)) { assert(isValidBaseClass(RD, cast(Super), IsVirtual)); (void)&isValidBaseClass; @@ -1209,7 +1182,7 @@ return getSubRegion(RD, Super); } -const CXXThisRegion* +const CXXThisRegion * MemRegionManager::getCXXThisRegion(QualType thisPointerTy, const LocationContext *LC) { const auto *PT = thisPointerTy->getAs(); @@ -1230,7 +1203,7 @@ return getSubRegion(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(MS) || - isa(MS); + return isa(MS) || isa(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(R)->getSuperRegion(); - continue; - default: - break; + case MemRegion::ElementRegionKind: + case MemRegion::FieldRegionKind: + case MemRegion::ObjCIvarRegionKind: + case MemRegion::CXXBaseObjectRegionKind: + case MemRegion::CXXDerivedObjectRegionKind: + R = cast(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() && 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(this)->LazyInitializeReferencedVars(); + const_cast(this)->LazyInitializeReferencedVars(); auto *Vec = static_cast *>(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(this)->LazyInitializeReferencedVars(); + const_cast(this)->LazyInitializeReferencedVars(); auto *Vec = static_cast *>(ReferencedVars); - if (Vec == (void*) 0x1) + if (Vec == (void *)0x1) return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr); auto *VecOriginal = diff --git a/clang/test/Analysis/pointer-to-member.cpp b/clang/test/Analysis/pointer-to-member.cpp --- a/clang/test/Analysis/pointer-to-member.cpp +++ b/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(derived_field); + clang_analyzer_eval(base.*base_field == 5); // expected-warning {{TRUE}} +} +} // namespace testPointerToMemberViaStaticCast + namespace testAnonymousMember { struct A { int a;