diff options
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/MemRegion.cpp | 27 | ||||
-rw-r--r-- | clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp | 29 |
2 files changed, 49 insertions, 7 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index 0a29a050..02d1358a 100644 --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -722,6 +722,13 @@ std::string MemRegion::getDescriptiveName(bool UseQuotes) const { SmallString<50> buf; llvm::raw_svector_ostream os(buf); + // Enclose subject with single quotes if needed. + auto QuoteIfNeeded = [UseQuotes](const Twine &Subject) -> std::string { + if (UseQuotes) + return ("'" + Subject + "'").str(); + return Subject.str(); + }; + // Obtain array indices to add them to the variable name. const ElementRegion *ER = nullptr; while ((ER = R->getAs<ElementRegion>())) { @@ -751,12 +758,20 @@ std::string MemRegion::getDescriptiveName(bool UseQuotes) const { } // Get variable name. - if (R && R->canPrintPrettyAsExpr()) { - R->printPrettyAsExpr(os); - if (UseQuotes) - return (llvm::Twine("'") + os.str() + ArrayIndices + "'").str(); - else - return (llvm::Twine(os.str()) + ArrayIndices).str(); + if (R) { + // MemRegion can be pretty printed. + if (R->canPrintPrettyAsExpr()) { + R->printPrettyAsExpr(os); + return QuoteIfNeeded(llvm::Twine(os.str()) + ArrayIndices); + } + + // FieldRegion may have ElementRegion as SuperRegion. + if (const auto *FR = R->getAs<FieldRegion>()) { + std::string Super = FR->getSuperRegion()->getDescriptiveName(false); + if (Super.empty()) + return ""; + return QuoteIfNeeded(Super + "." + FR->getDecl()->getName()); + } } return VariableName; diff --git a/clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp b/clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp index b13e712..0f6e49b 100644 --- a/clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp +++ b/clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp @@ -12,7 +12,6 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" #include "gtest/gtest.h" -#include <fstream> using namespace clang; using namespace ento; @@ -143,4 +142,32 @@ void top() { EXPECT_EQ(Output, "DescriptiveNameChecker: array[x]\n"); } +TEST(MemRegionDescriptiveNameTest, FieldRegWithSuperElementReg) { + StringRef Code = R"cpp( +void reportDescriptiveName(int *p); +struct val_struct { int val; }; +extern struct val_struct val_struct_array[3]; +void top() { + reportDescriptiveName(&val_struct_array[0].val); +})cpp"; + + std::string Output; + ASSERT_TRUE(runChecker(Code, Output)); + EXPECT_EQ(Output, "DescriptiveNameChecker: val_struct_array[0].val\n"); +} + +TEST(MemRegionDescriptiveNameTest, FieldRegWithSuperMultidimElementReg) { + StringRef Code = R"cpp( +void reportDescriptiveName(int *p); +struct val_struct { int val; }; +extern struct val_struct val_struct_array[3][4]; +void top() { + reportDescriptiveName(&val_struct_array[1][2].val); +})cpp"; + + std::string Output; + ASSERT_TRUE(runChecker(Code, Output)); + EXPECT_EQ(Output, "DescriptiveNameChecker: val_struct_array[1][2].val\n"); +} + } // namespace |