From dac182990dabe8d15cfb8079aba68df2ded015aa Mon Sep 17 00:00:00 2001 From: Timm Baeder Date: Sun, 18 Aug 2024 08:59:34 +0200 Subject: [PATCH] [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. --- clang/lib/AST/ByteCode/Interp.h | 11 +++++++++++ clang/lib/AST/ByteCode/Pointer.cpp | 2 +- clang/lib/AST/ByteCode/Pointer.h | 2 +- clang/test/AST/ByteCode/codegen.c | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 clang/test/AST/ByteCode/codegen.c diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 9891e3dba0d309..6cb7a42482ab25 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(Offset) * Ptr.elemSize(); + if constexpr (Op == ArithOp::Add) + S.Stk.push(V + O, Ptr.asIntPointer().Desc); + else + S.Stk.push(V - O, Ptr.asIntPointer().Desc); + return true; + } + uint64_t MaxIndex = static_cast(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 e39459578a5f52..5b9e83764cfa50 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 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