[clang] Adapted MemRegion::getDescriptiveName to handle ElementRegions (PR #85104)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 13 09:14:55 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-static-analyzer-1
Author: None (T-Gruber)
<details>
<summary>Changes</summary>
Fixes https://github.com/llvm/llvm-project/issues/84463
Changes:
- Adapted MemRegion::getDescriptiveName
- Added unittest to check name for a given clang::ento::ElementRegion
- Some format changes due to clang-format
---
Patch is 28.10 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/85104.diff
3 Files Affected:
- (modified) clang/lib/StaticAnalyzer/Core/MemRegion.cpp (+110-134)
- (modified) clang/unittests/StaticAnalyzer/CMakeLists.txt (+1)
- (added) clang/unittests/StaticAnalyzer/MemRegionTest.cpp (+56)
``````````diff
diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index 16db6b249dc92b..89791bd88001e3 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -66,7 +66,7 @@ using namespace ento;
//===----------------------------------------------------------------------===//
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);
@@ -82,7 +82,7 @@ RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1,
}
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);
@@ -97,9 +97,9 @@ RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
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 @@ MemRegionManager::~MemRegionManager() = default;
// 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 @@ bool SubRegion::isSubRegionOf(const MemRegion* R) const {
}
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)) {
@@ -178,9 +178,7 @@ ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg)
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);
@@ -251,26 +249,25 @@ void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
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);
@@ -292,9 +289,9 @@ void FieldRegion::Profile(llvm::FoldingSetNodeID &ID) const {
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);
@@ -328,58 +325,56 @@ void ParamVarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
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);
@@ -387,13 +382,12 @@ void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
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);
}
@@ -417,8 +411,7 @@ void CXXLifetimeExtendedObjectRegion::Profile(
}
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);
@@ -462,9 +455,7 @@ void SubRegion::anchor() {}
// 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;
@@ -500,7 +491,7 @@ void BlockDataRegion::dumpToStream(raw_ostream &os) const {
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 {
@@ -526,9 +517,7 @@ void CXXDerivedObjectRegion::dumpToStream(raw_ostream &os) const {
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()
@@ -622,13 +611,9 @@ void ParamVarRegion::dumpToStream(raw_ostream &os) const {
}
}
-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.");
@@ -656,17 +641,13 @@ void ParamVarRegion::printPrettyAsExpr(raw_ostream &os) const {
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();
@@ -684,7 +665,8 @@ void FieldRegion::printPretty(raw_ostream &os) const {
printPrettyAsExpr(os);
os << "'";
} else {
- os << "field " << "\'" << getDecl()->getName() << "'";
+ os << "field "
+ << "\'" << getDecl()->getName() << "'";
}
}
@@ -720,14 +702,20 @@ std::string MemRegion::getDescriptiveName(bool UseQuotes) const {
CI->getValue().toString(Idx);
ArrayIndices = (llvm::Twine("[") + Idx.str() + "]" + ArrayIndices).str();
}
- // If not a ConcreteInt, try to obtain the variable
- // name by calling 'getDescriptiveName' recursively.
- else {
- std::string Idx = ER->getDescriptiveName(false);
- if (!Idx.empty()) {
- ArrayIndices = (llvm::Twine("[") + Idx + "]" + ArrayIndices).str();
+ // Index is a SymbolVal.
+ else if (auto SI = ER->getIndex().getAs<nonloc::SymbolVal>()) {
+ if (auto SR = SI->getAsSymbol()) {
+ if (auto OR = SR->getOriginRegion()) {
+ std::string Idx = OR->getDescriptiveName(false);
+ ArrayIndices = (llvm::Twine("[") + Idx + "]" + ArrayIndices).str();
+ }
}
}
+ // Index is neither a ConcreteInt nor SymbolVal, give up and return.
+ else {
+ assert(false && "we should have a descriptive name");
+ return "";
+ }
R = ER->getSuperRegion();
}
@@ -862,7 +850,7 @@ DefinedOrUnknownSVal MemRegionManager::getStaticSize(const MemRegion *MR,
}
template <typename REG>
-const REG *MemRegionManager::LazyAllocate(REG*& region) {
+const REG *MemRegionManager::LazyAllocate(REG *®ion) {
if (!region) {
region = new (A) REG(*this);
}
@@ -871,7 +859,7 @@ const REG *MemRegionManager::LazyAllocate(REG*& region) {
}
template <typename REG, typename ARG>
-const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
+const REG *MemRegionManager::LazyAllocate(REG *®ion, ARG a) {
if (!region) {
region = new (A) REG(this, a);
}
@@ -879,7 +867,7 @@ const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
return region;
}
-const StackLocalsSpaceRegion*
+const StackLocalsSpaceRegion *
MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
assert(STC);
StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
@@ -903,9 +891,9 @@ MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
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);
@@ -940,13 +928,14 @@ const CodeSpaceRegion *MemRegionManager::getCodeRegion() {
// 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()));
}
@@ -1018,16 +1007,16 @@ const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
}
- // 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 *>();
@@ -1041,8 +1030,7 @@ const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
isa<ParmVarDecl, ImplicitParamDecl>(D)
? static_cast<const MemRegion *>(getStackArgumentsRegion(STC))
: static_cast<const MemRegion *>(getStackLocalsRegion(STC));
- }
- else {
+ } else {
assert(D->isStaticLocal());
const Decl *STCD = STC->getDecl();
if (isa<FunctionDecl, ObjCMethodDecl>(STCD))
@@ -1064,13 +1052,10 @@ const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
}
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();
}
}
@@ -1099,17 +1084,14 @@ MemRegionManager::getParamVarRegion(const Expr *OriginExpr, unsigned Index,
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 {
bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
// ARC managed blocks can be initialized on stack or directly in heap
@@ -1131,7 +1113,7 @@ MemRegionManager::getBlockDataRegion(const BlockCodeRegion *BC,
return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg);
}
-const CompoundLiteralRegion*
+const CompoundLiteralRegion *
MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
const LocationContext *LC) {
const MemSpaceRegion *sReg = nullptr;
@@ -1147,17 +1129,17 @@ MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
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) {
@@ -1192,19 +1174,19 @@ const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
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 S...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/85104
More information about the cfe-commits
mailing list