[clang] [clang][dataflow] Add a test for context-sensitive analysis on a self-referential class. (PR #66359)

via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 14 04:07:05 PDT 2023


https://github.com/martinboehme created https://github.com/llvm/llvm-project/pull/66359:

The test demonstrates that the `this` pointer seen in the constructor has the
same value as the address of the variable the object is constructed into.


>From c2219d46c4cdb5e82bf98d0249412c95c0781c97 Mon Sep 17 00:00:00 2001
From: Martin Braenne <mboehme at google.com>
Date: Thu, 14 Sep 2023 11:06:24 +0000
Subject: [PATCH] [clang][dataflow] Add a test for context-sensitive analysis
 on a self-referential class.

The test demonstrates that the `this` pointer seen in the constructor has the
same value as the address of the variable the object is constructed into.
---
 .../Analysis/FlowSensitive/TransferTest.cpp   | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index 05ee5df0e95a433..e29dc86d7aaffb3 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -5457,6 +5457,41 @@ TEST(TransferTest, ContextSensitiveConstructorDefault) {
       {BuiltinOptions{ContextSensitiveOptions{}}});
 }
 
+TEST(TransferTest, ContextSensitiveSelfReferentialClass) {
+  // Test that the `this` pointer seen in the constructor has the same value
+  // as the address of the variable the object is constructed into.
+  std::string Code = R"(
+    class MyClass {
+    public:
+      MyClass() : Self(this) {}
+      MyClass *Self;
+    };
+
+    void target() {
+      MyClass MyObj;
+      MyClass *SelfPtr = MyObj.Self;
+      // [[p]]
+    }
+  )";
+  runDataflow(
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+
+        const ValueDecl *MyObjDecl = findValueDecl(ASTCtx, "MyObj");
+        ASSERT_THAT(MyObjDecl, NotNull());
+
+        const ValueDecl *SelfDecl = findValueDecl(ASTCtx, "SelfPtr");
+        ASSERT_THAT(SelfDecl, NotNull());
+
+        const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+        auto &SelfVal = *cast<PointerValue>(Env.getValue(*SelfDecl));
+        EXPECT_EQ(Env.getStorageLocation(*MyObjDecl), &SelfVal.getPointeeLoc());
+      },
+      {BuiltinOptions{ContextSensitiveOptions{}}});
+}
+
 TEST(TransferTest, UnnamedBitfieldInitializer) {
   std::string Code = R"(
     struct B {};



More information about the cfe-commits mailing list