tbaeder updated this revision to Diff 480873. tbaeder marked 2 inline comments as done.
CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139185/new/ https://reviews.llvm.org/D139185 Files: clang/lib/AST/Interp/ByteCodeEmitter.cpp clang/lib/AST/Interp/PrimType.h clang/lib/AST/Interp/Source.h Index: clang/lib/AST/Interp/Source.h =================================================================== --- clang/lib/AST/Interp/Source.h +++ clang/lib/AST/Interp/Source.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_AST_INTERP_SOURCE_H #define LLVM_CLANG_AST_INTERP_SOURCE_H +#include "PrimType.h" #include "clang/AST/Decl.h" #include "clang/AST/Stmt.h" #include "llvm/Support/Endian.h" @@ -47,9 +48,10 @@ /// Reads data and advances the pointer. template <typename T> std::enable_if_t<!std::is_pointer<T>::value, T> read() { + assert(aligned(Ptr)); using namespace llvm::support; T Value = endian::read<T, endianness::native, 1>(Ptr); - Ptr += sizeof(T); + Ptr += align(sizeof(T)); return Value; } Index: clang/lib/AST/Interp/PrimType.h =================================================================== --- clang/lib/AST/Interp/PrimType.h +++ clang/lib/AST/Interp/PrimType.h @@ -62,6 +62,13 @@ return ((Size + alignof(void *) - 1) / alignof(void *)) * alignof(void *); } +constexpr bool aligned(uintptr_t Value) { return Value == align(Value); } +static_assert(aligned(sizeof(void *))); + +static inline bool aligned(const void *P) { + return aligned(reinterpret_cast<uintptr_t>(P)); +} + inline bool isPrimitiveIntegral(PrimType Type) { switch (Type) { case PT_Bool: Index: clang/lib/AST/Interp/ByteCodeEmitter.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -116,7 +116,8 @@ using namespace llvm::support; /// Rewrite the operand of all jumps to this label. - void *Location = Code.data() + Reloc - sizeof(int32_t); + void *Location = Code.data() + Reloc - align(sizeof(int32_t)); + assert(aligned(Location)); const int32_t Offset = Target - static_cast<int64_t>(Reloc); endian::write<int32_t, endianness::native, 1>(Location, Offset); } @@ -126,7 +127,9 @@ int32_t ByteCodeEmitter::getOffset(LabelTy Label) { // Compute the PC offset which the jump is relative to. - const int64_t Position = Code.size() + sizeof(Opcode) + sizeof(int32_t); + const int64_t Position = + Code.size() + align(sizeof(Opcode)) + align(sizeof(int32_t)); + assert(aligned(Position)); // If target is known, compute jump offset. auto It = LabelOffsets.find(Label); @@ -162,13 +165,17 @@ return; } + // Access must be aligned! + size_t ValPos = align(Code.size()); + Size = align(Size); + assert(aligned(ValPos + Size)); + Code.resize(ValPos + Size); + if constexpr (!std::is_pointer_v<T>) { - const char *Data = reinterpret_cast<const char *>(&Val); - Code.insert(Code.end(), Data, Data + Size); + new (Code.data() + ValPos) T(Val); } else { uint32_t ID = P.getOrCreateNativePointer(Val); - const char *Data = reinterpret_cast<const char *>(&ID); - Code.insert(Code.end(), Data, Data + Size); + new (Code.data() + ValPos) uint32_t(ID); } }
Index: clang/lib/AST/Interp/Source.h =================================================================== --- clang/lib/AST/Interp/Source.h +++ clang/lib/AST/Interp/Source.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_AST_INTERP_SOURCE_H #define LLVM_CLANG_AST_INTERP_SOURCE_H +#include "PrimType.h" #include "clang/AST/Decl.h" #include "clang/AST/Stmt.h" #include "llvm/Support/Endian.h" @@ -47,9 +48,10 @@ /// Reads data and advances the pointer. template <typename T> std::enable_if_t<!std::is_pointer<T>::value, T> read() { + assert(aligned(Ptr)); using namespace llvm::support; T Value = endian::read<T, endianness::native, 1>(Ptr); - Ptr += sizeof(T); + Ptr += align(sizeof(T)); return Value; } Index: clang/lib/AST/Interp/PrimType.h =================================================================== --- clang/lib/AST/Interp/PrimType.h +++ clang/lib/AST/Interp/PrimType.h @@ -62,6 +62,13 @@ return ((Size + alignof(void *) - 1) / alignof(void *)) * alignof(void *); } +constexpr bool aligned(uintptr_t Value) { return Value == align(Value); } +static_assert(aligned(sizeof(void *))); + +static inline bool aligned(const void *P) { + return aligned(reinterpret_cast<uintptr_t>(P)); +} + inline bool isPrimitiveIntegral(PrimType Type) { switch (Type) { case PT_Bool: Index: clang/lib/AST/Interp/ByteCodeEmitter.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -116,7 +116,8 @@ using namespace llvm::support; /// Rewrite the operand of all jumps to this label. - void *Location = Code.data() + Reloc - sizeof(int32_t); + void *Location = Code.data() + Reloc - align(sizeof(int32_t)); + assert(aligned(Location)); const int32_t Offset = Target - static_cast<int64_t>(Reloc); endian::write<int32_t, endianness::native, 1>(Location, Offset); } @@ -126,7 +127,9 @@ int32_t ByteCodeEmitter::getOffset(LabelTy Label) { // Compute the PC offset which the jump is relative to. - const int64_t Position = Code.size() + sizeof(Opcode) + sizeof(int32_t); + const int64_t Position = + Code.size() + align(sizeof(Opcode)) + align(sizeof(int32_t)); + assert(aligned(Position)); // If target is known, compute jump offset. auto It = LabelOffsets.find(Label); @@ -162,13 +165,17 @@ return; } + // Access must be aligned! + size_t ValPos = align(Code.size()); + Size = align(Size); + assert(aligned(ValPos + Size)); + Code.resize(ValPos + Size); + if constexpr (!std::is_pointer_v<T>) { - const char *Data = reinterpret_cast<const char *>(&Val); - Code.insert(Code.end(), Data, Data + Size); + new (Code.data() + ValPos) T(Val); } else { uint32_t ID = P.getOrCreateNativePointer(Val); - const char *Data = reinterpret_cast<const char *>(&ID); - Code.insert(Code.end(), Data, Data + Size); + new (Code.data() + ValPos) uint32_t(ID); } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits