[clang] 712ab80 - [clang][Interp] Properly adjust instance pointer in virtual calls (#102800)

via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 11 01:09:06 PDT 2024


Author: Timm Baeder
Date: 2024-08-11T10:09:03+02:00
New Revision: 712ab805140068a7b4719a38de3fee904841dbb3

URL: https://github.com/llvm/llvm-project/commit/712ab805140068a7b4719a38de3fee904841dbb3
DIFF: https://github.com/llvm/llvm-project/commit/712ab805140068a7b4719a38de3fee904841dbb3.diff

LOG: [clang][Interp] Properly adjust instance pointer in virtual calls (#102800)

`getDeclPtr()` will not just return what we want, but in this case a
pointer to the `vu` local variable.

Added: 
    

Modified: 
    clang/lib/AST/Interp/Interp.h
    clang/test/AST/Interp/records.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index af33d507ef8d7..67b3fc5064509 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -2633,9 +2633,10 @@ inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func,
         ThisPtr.getFieldDesc()->getType()->getAsCXXRecordDecl();
     if (Func->getParentDecl()->isDerivedFrom(ThisFieldDecl)) {
       // If the function we call is further DOWN the hierarchy than the
-      // FieldDesc of our pointer, just get the DeclDesc instead, which
-      // is the furthest we might go up in the hierarchy.
-      ThisPtr = ThisPtr.getDeclPtr();
+      // FieldDesc of our pointer, just go up the hierarchy of this field
+      // the furthest we can go.
+      while (ThisPtr.isBaseClass())
+        ThisPtr = ThisPtr.getBase();
     }
   }
 

diff  --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp
index 343665003c23e..e620bf9e0e041 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1572,3 +1572,27 @@ namespace ctorOverrider {
   constexpr Covariant1 cb;
 }
 #endif
+
+#if __cplusplus >= 202002L
+namespace VirtDtor {
+  struct X { char *p; constexpr ~X() { *p++ = 'X'; } };
+  struct Y : X { int y; virtual constexpr ~Y() { *p++ = 'Y'; } };
+  struct Z : Y { int z; constexpr ~Z() override { *p++ = 'Z'; } };
+
+  union VU {
+    constexpr VU() : z() {}
+    constexpr ~VU() {}
+    Z z;
+  };
+
+  constexpr char virt_dtor(int mode, const char *expected) {
+    char buff[4] = {};
+    VU vu;
+    vu.z.p = buff;
+
+    ((Y&)vu.z).~Y();
+    return true;
+  }
+  static_assert(virt_dtor(0, "ZYX"));
+}
+#endif


        


More information about the cfe-commits mailing list