Alexander_Droste updated this revision to Diff 48940. Alexander_Droste added a comment.
Changes: - remove `if (VariableName.size() && VariableName.back() == '\'')` check - call `getVariableName` for index if Region is no `ConcreteInt` Hi Gábor, sorry about the delay! Here's the updated patch. Is it really possible to reduce string copying in this case, with the help of `llvm::Twine`? The problem with `llvm::Twine` seems to me that it cannot be modified after initialisation. So there's no way to do sth. like: `Twine t("a" + "b"); t += "c"`. A new Twine object needs to be created for each subsequent concatenation. Do you have an idea how twine could be applied here? Else I would claim that this function gets only used for diagnostics why this level of efficiency might not be required. http://reviews.llvm.org/D16044 Files: include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h lib/StaticAnalyzer/Core/MemRegion.cpp Index: include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -150,6 +150,14 @@ template<typename RegionTy> const RegionTy* getAs() const; virtual bool isBoundable() const { return false; } + + /// Get variable name for memory region. The name is obtained from + /// the variable/field declaration retrieved from the memory region. + /// Regions that point to an element of an array are returned as: "arr[0]". + /// Regions that point to a struct are returned as: "st.var". + /// + /// \returns variable name for memory region + std::string getVariableName() const; }; /// MemSpaceRegion - A memory region that represents a "memory space"; Index: lib/StaticAnalyzer/Core/MemRegion.cpp =================================================================== --- lib/StaticAnalyzer/Core/MemRegion.cpp +++ lib/StaticAnalyzer/Core/MemRegion.cpp @@ -632,6 +632,48 @@ superRegion->printPrettyAsExpr(os); } +std::string MemRegion::getVariableName() const { + std::string VariableName{""}; + std::string ArrayIndices{""}; + const clang::ento::MemRegion *R = this; + llvm::SmallString<50> buf; + llvm::raw_svector_ostream os(buf); + + // Obtain array indices to add them to the variable name. + const clang::ento::ElementRegion *ER = nullptr; + while ((ER = R->getAs<clang::ento::ElementRegion>())) { + std::string idx{""}; + // Index is a ConcreteInt. + if (auto CI = ER->getIndex().getAs<clang::ento::nonloc::ConcreteInt>()) { + llvm::SmallString<2> intValAsString; + CI->getValue().toString(intValAsString); + idx = {intValAsString.begin(), intValAsString.end()}; + } + // If not a ConcreteInt, try to obtain the variable + // name by calling 'getVariableName()' recursively. + else { + idx = R->getVariableName(); + if (!idx.empty()) { + // Exclude single quotes surrounding the index var name. + idx = idx.substr(1, idx.size() - 2); + } + } + ArrayIndices += "]" + idx + "["; + R = ER->getSuperRegion(); + } + std::reverse(ArrayIndices.begin(), ArrayIndices.end()); + + // Get variable name. + if (R && R->canPrintPretty()) { + R->printPretty(os); + VariableName = os.str(); + // Combine variable name with indices. + VariableName.insert(VariableName.size() - 1, ArrayIndices); + } + + return VariableName; +} + //===----------------------------------------------------------------------===// // MemRegionManager methods. //===----------------------------------------------------------------------===//
Index: include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -150,6 +150,14 @@ template<typename RegionTy> const RegionTy* getAs() const; virtual bool isBoundable() const { return false; } + + /// Get variable name for memory region. The name is obtained from + /// the variable/field declaration retrieved from the memory region. + /// Regions that point to an element of an array are returned as: "arr[0]". + /// Regions that point to a struct are returned as: "st.var". + /// + /// \returns variable name for memory region + std::string getVariableName() const; }; /// MemSpaceRegion - A memory region that represents a "memory space"; Index: lib/StaticAnalyzer/Core/MemRegion.cpp =================================================================== --- lib/StaticAnalyzer/Core/MemRegion.cpp +++ lib/StaticAnalyzer/Core/MemRegion.cpp @@ -632,6 +632,48 @@ superRegion->printPrettyAsExpr(os); } +std::string MemRegion::getVariableName() const { + std::string VariableName{""}; + std::string ArrayIndices{""}; + const clang::ento::MemRegion *R = this; + llvm::SmallString<50> buf; + llvm::raw_svector_ostream os(buf); + + // Obtain array indices to add them to the variable name. + const clang::ento::ElementRegion *ER = nullptr; + while ((ER = R->getAs<clang::ento::ElementRegion>())) { + std::string idx{""}; + // Index is a ConcreteInt. + if (auto CI = ER->getIndex().getAs<clang::ento::nonloc::ConcreteInt>()) { + llvm::SmallString<2> intValAsString; + CI->getValue().toString(intValAsString); + idx = {intValAsString.begin(), intValAsString.end()}; + } + // If not a ConcreteInt, try to obtain the variable + // name by calling 'getVariableName()' recursively. + else { + idx = R->getVariableName(); + if (!idx.empty()) { + // Exclude single quotes surrounding the index var name. + idx = idx.substr(1, idx.size() - 2); + } + } + ArrayIndices += "]" + idx + "["; + R = ER->getSuperRegion(); + } + std::reverse(ArrayIndices.begin(), ArrayIndices.end()); + + // Get variable name. + if (R && R->canPrintPretty()) { + R->printPretty(os); + VariableName = os.str(); + // Combine variable name with indices. + VariableName.insert(VariableName.size() - 1, ArrayIndices); + } + + return VariableName; +} + //===----------------------------------------------------------------------===// // MemRegionManager methods. //===----------------------------------------------------------------------===//
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits