This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rGad2fb01cb68d: [clang][Interp] Fix dereferencing arrays with no offset applied (authored by tbaeder).
Changed prior to commit: https://reviews.llvm.org/D137082?vs=472887&id=492041#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D137082/new/ https://reviews.llvm.org/D137082 Files: clang/lib/AST/Interp/Pointer.h clang/test/AST/Interp/arrays.cpp Index: clang/test/AST/Interp/arrays.cpp =================================================================== --- clang/test/AST/Interp/arrays.cpp +++ clang/test/AST/Interp/arrays.cpp @@ -42,6 +42,21 @@ 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, ""); Index: clang/lib/AST/Interp/Pointer.h =================================================================== --- clang/lib/AST/Interp/Pointer.h +++ clang/lib/AST/Interp/Pointer.h @@ -225,6 +225,10 @@ 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 @@ /// 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); }
Index: clang/test/AST/Interp/arrays.cpp =================================================================== --- clang/test/AST/Interp/arrays.cpp +++ clang/test/AST/Interp/arrays.cpp @@ -42,6 +42,21 @@ 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, ""); Index: clang/lib/AST/Interp/Pointer.h =================================================================== --- clang/lib/AST/Interp/Pointer.h +++ clang/lib/AST/Interp/Pointer.h @@ -225,6 +225,10 @@ 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 @@ /// 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); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits