[clang] Fieldregion descript name (PR #112313)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 14 22:54:43 PDT 2024


https://github.com/T-Gruber created https://github.com/llvm/llvm-project/pull/112313

The current implementation of MemRegion::getDescriptiveName fails for FieldRegions whose SuperRegion is an ElementRegion. As outlined below:
```Cpp
struct val_struct { int val; };
extern struct val_struct val_struct_array[3];

void func(){
  // FieldRegion with ElementRegion as SuperRegion.
  val_struct_array[0].val;
}
```

For this special case, the expression cannot be pretty printed and must therefore be obtained separately. 

>From dd562bb3d505c43070ceb8af51359cc66860a0ea Mon Sep 17 00:00:00 2001
From: "tobias.gruber" <tobias.gruber at concentrio.io>
Date: Tue, 15 Oct 2024 07:19:12 +0200
Subject: [PATCH 1/2] Handle FieldRegions with ElementRegions as SuperRegions
 in getDescriptiveName

---
 clang/lib/StaticAnalyzer/Core/MemRegion.cpp   | 25 +++++++++++++++----
 .../MemRegionDescriptiveNameTest.cpp          | 14 +++++++++++
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index 693791c3aee8b9..4144cff8607926 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -751,12 +751,27 @@ 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
+  if (R) {
+    // MemRegion can be pretty printed.
+    if (R->canPrintPrettyAsExpr()) {
+      R->printPrettyAsExpr(os);
+      if (UseQuotes)
+        return (llvm::Twine("'") + os.str() + ArrayIndices + "'").str();
       return (llvm::Twine(os.str()) + ArrayIndices).str();
+    }
+
+    // FieldRegion may have ElementRegion as SuperRegion.
+    if (const clang::ento::FieldRegion *FR =
+            R->getAs<clang::ento::FieldRegion>()) {
+      std::string Super = FR->getSuperRegion()->getDescriptiveName(false);
+      if (Super.empty())
+        return "";
+
+      if (UseQuotes)
+        return (llvm::Twine("'") + Super + "." + FR->getDecl()->getName() + "'")
+            .str();
+      return (llvm::Twine(Super) + "." + FR->getDecl()->getName()).str();
+    }
   }
 
   return VariableName;
diff --git a/clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp b/clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp
index b13e7123ee524d..fe5defd1d47915 100644
--- a/clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp
+++ b/clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp
@@ -143,4 +143,18 @@ 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");
+}
+
 } // namespace

>From d8837ca3427e04d0d8a070ddce93da1485f2835f Mon Sep 17 00:00:00 2001
From: "tobias.gruber" <tobias.gruber at concentrio.io>
Date: Tue, 15 Oct 2024 07:20:21 +0200
Subject: [PATCH 2/2] Remove unneeded include

---
 clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp b/clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp
index fe5defd1d47915..966e5c0e9a6124 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;



More information about the cfe-commits mailing list