Author: Timm Bäder Date: 2023-01-25T11:21:31+01:00 New Revision: ad2fb01cb68dc17594d2a923da90f5e01e127cdf
URL: https://github.com/llvm/llvm-project/commit/ad2fb01cb68dc17594d2a923da90f5e01e127cdf DIFF: https://github.com/llvm/llvm-project/commit/ad2fb01cb68dc17594d2a923da90f5e01e127cdf.diff LOG: [clang][Interp] Fix dereferencing arrays with no offset applied A pointer to an array and a pointer to the first element of the array are not the same in the interpreter, so handle this specially in deref(). Differential Revision: https://reviews.llvm.org/D137082 Added: Modified: clang/lib/AST/Interp/Pointer.h clang/test/AST/Interp/arrays.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h index 1462d01c24126..489884a256598 100644 --- a/clang/lib/AST/Interp/Pointer.h +++ b/clang/lib/AST/Interp/Pointer.h @@ -225,6 +225,10 @@ class Pointer { return Offset - Base - Adjust; } + /// Whether this array refers to an array, but not + /// to the first element. + bool isArrayRoot() const { return inArray() && Offset == Base; } + /// Checks if the innermost field is an array. bool inArray() const { return getFieldDesc()->IsArray; } /// Checks if the structure is a primitive array. @@ -306,6 +310,10 @@ class Pointer { /// Dereferences the pointer, if it's live. template <typename T> T &deref() const { assert(isLive() && "Invalid pointer"); + if (isArrayRoot()) + return *reinterpret_cast<T *>(Pointee->rawData() + Base + + sizeof(InitMap *)); + return *reinterpret_cast<T *>(Pointee->rawData() + Offset); } diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp index cd8d37442e089..3c0eaefeb7965 100644 --- a/clang/test/AST/Interp/arrays.cpp +++ b/clang/test/AST/Interp/arrays.cpp @@ -42,6 +42,21 @@ constexpr int getElement(const int *Arr, int index) { return *(Arr + index); } +constexpr int derefPtr(const int *d) { + return *d; +} +static_assert(derefPtr(data) == 5, ""); + +constexpr int storePtr() { + int b[] = {1,2,3,4}; + int *c = b; + + *c = 4; + return *c; +} +static_assert(storePtr() == 4, ""); + + static_assert(getElement(data, 1) == 4, ""); static_assert(getElement(data, 4) == 1, ""); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits