[clang] [clang][bytecode] IntPointer::atOffset() should append (PR #104686)

via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 17 15:30:07 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

... to current offset. This breaks other tests which this commit also fixes. Namely, getIndex() should return the integer representation for non-block pointers.

---
Full diff: https://github.com/llvm/llvm-project/pull/104686.diff


4 Files Affected:

- (modified) clang/lib/AST/ByteCode/Interp.h (+11) 
- (modified) clang/lib/AST/ByteCode/Pointer.cpp (+1-1) 
- (modified) clang/lib/AST/ByteCode/Pointer.h (+1-1) 
- (added) clang/test/AST/ByteCode/codegen.c (+19) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index c3ce21cb13770e..2332a479e79cde 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -1853,6 +1853,17 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
   if (!CheckArray(S, OpPC, Ptr))
     return false;
 
+  // This is much simpler for integral pointers, so handle them first.
+  if (Ptr.isIntegralPointer()) {
+    uint64_t V = Ptr.getIntegerRepresentation();
+    uint64_t O = static_cast<uint64_t>(Offset) * Ptr.elemSize();
+    if constexpr (Op == ArithOp::Add)
+      S.Stk.push<Pointer>(V + O, Ptr.asIntPointer().Desc);
+    else
+      S.Stk.push<Pointer>(V - O, Ptr.asIntPointer().Desc);
+    return true;
+  }
+
   uint64_t MaxIndex = static_cast<uint64_t>(Ptr.getNumElems());
   uint64_t Index;
   if (Ptr.isOnePastEnd())
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 466e61666c76e9..ccab3b7f626811 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -647,5 +647,5 @@ IntPointer IntPointer::atOffset(const ASTContext &ASTCtx,
   uint64_t FieldOffset =
       ASTCtx.toCharUnitsFromBits(Layout.getFieldOffset(FieldIndex))
           .getQuantity();
-  return IntPointer{this->Desc, FieldOffset};
+  return IntPointer{this->Desc, this->Value + FieldOffset};
 }
diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index 8db081c0ec82b3..ba30449977376b 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -571,7 +571,7 @@ class Pointer {
   /// Returns the index into an array.
   int64_t getIndex() const {
     if (!isBlockPointer())
-      return 0;
+      return getIntegerRepresentation();
 
     if (isZero())
       return 0;
diff --git a/clang/test/AST/ByteCode/codegen.c b/clang/test/AST/ByteCode/codegen.c
new file mode 100644
index 00000000000000..8434992823010e
--- /dev/null
+++ b/clang/test/AST/ByteCode/codegen.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -o - %s -fexperimental-new-constant-interpreter | FileCheck %s
+
+typedef __INTPTR_TYPE__ intptr_t;
+
+const intptr_t Z1 = (intptr_t)(((char*)-1LL) + 1);
+// CHECK: @Z1 = constant i64 0
+
+const intptr_t Z2 = (intptr_t)(((char*)1LL) - 1);
+// CHECK: @Z2 = constant i64 0
+
+struct A {
+  char num_fields;
+};
+struct B {
+  char a, b[1];
+};
+const int A = (char *)(&( (struct B *)(16) )->b[0]) - (char *)(16);
+// CHECK: @A = constant i32 1

``````````

</details>


https://github.com/llvm/llvm-project/pull/104686


More information about the cfe-commits mailing list