Author: Timm Baeder
Date: 2024-08-18T08:59:34+02:00
New Revision: dac182990dabe8d15cfb8079aba68df2ded015aa

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

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

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

Added: 
    clang/test/AST/ByteCode/codegen.c

Modified: 
    clang/lib/AST/ByteCode/Interp.h
    clang/lib/AST/ByteCode/Pointer.cpp
    clang/lib/AST/ByteCode/Pointer.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 9891e3dba0d30..6cb7a42482ab2 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 e39459578a5f5..5b9e83764cfa5 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -654,5 +654,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 8db081c0ec82b..ba30449977376 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 0000000000000..8434992823010
--- /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


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to