[clang] 1221af9 - [clang][Interp] Use placement new to construct opcode args into vector
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 19 00:24:20 PST 2023
Author: Timm Bäder
Date: 2023-01-19T09:22:57+01:00
New Revision: 1221af99281c87d35c65110a75f87893ff0fc947
URL: https://github.com/llvm/llvm-project/commit/1221af99281c87d35c65110a75f87893ff0fc947
DIFF: https://github.com/llvm/llvm-project/commit/1221af99281c87d35c65110a75f87893ff0fc947.diff
LOG: [clang][Interp] Use placement new to construct opcode args into vector
Differential Revision: https://reviews.llvm.org/D139185
Added:
Modified:
clang/lib/AST/Interp/ByteCodeEmitter.cpp
clang/lib/AST/Interp/PrimType.h
clang/lib/AST/Interp/Source.h
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
index ff2136d34872..4633d1e0823b 100644
--- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -116,7 +116,8 @@ void ByteCodeEmitter::emitLabel(LabelTy Label) {
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 @@ void ByteCodeEmitter::emitLabel(LabelTy Label) {
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 @@ static void emit(Program &P, std::vector<char> &Code, const T &Val,
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);
}
}
diff --git a/clang/lib/AST/Interp/PrimType.h b/clang/lib/AST/Interp/PrimType.h
index 8490c1f6548a..3a77c66c7437 100644
--- a/clang/lib/AST/Interp/PrimType.h
+++ b/clang/lib/AST/Interp/PrimType.h
@@ -59,6 +59,13 @@ constexpr size_t align(size_t Size) {
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:
diff --git a/clang/lib/AST/Interp/Source.h b/clang/lib/AST/Interp/Source.h
index de4ae559e4bb..99ffce34c12f 100644
--- a/clang/lib/AST/Interp/Source.h
+++ b/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 @@ class CodePtr final {
/// 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;
}
More information about the cfe-commits
mailing list