Skip to content

Commit b5c9cba

Browse files
authored
[clang][bytecode] Don't memcpy() FixedPoint values (#123599)
llvm::FixedPoint is not trivially copyable.
1 parent a733c1f commit b5c9cba

File tree

4 files changed

+45
-0
lines changed

4 files changed

+45
-0
lines changed

clang/lib/AST/ByteCode/ByteCodeEmitter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,12 @@ void emit(Program &P, std::vector<std::byte> &Code, const IntegralAP<true> &Val,
332332
emitSerialized(Code, Val, Success);
333333
}
334334

335+
template <>
336+
void emit(Program &P, std::vector<std::byte> &Code, const FixedPoint &Val,
337+
bool &Success) {
338+
emitSerialized(Code, Val, Success);
339+
}
340+
335341
template <typename... Tys>
336342
bool ByteCodeEmitter::emitOp(Opcode Op, const Tys &...Args,
337343
const SourceInfo &SI) {

clang/lib/AST/ByteCode/Disasm.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ inline IntegralAP<true> ReadArg<IntegralAP<true>>(Program &P, CodePtr &OpPC) {
6262
return I;
6363
}
6464

65+
template <> inline FixedPoint ReadArg<FixedPoint>(Program &P, CodePtr &OpPC) {
66+
FixedPoint I = FixedPoint::deserialize(*OpPC);
67+
OpPC += align(I.bytesToSerialize());
68+
return I;
69+
}
70+
6571
LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); }
6672

6773
LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const {

clang/lib/AST/ByteCode/FixedPoint.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,32 @@ class FixedPoint final {
9191
return ComparisonCategoryResult::Greater;
9292
}
9393

94+
size_t bytesToSerialize() const {
95+
return sizeof(uint32_t) + (V.getValue().getBitWidth() / CHAR_BIT);
96+
}
97+
98+
void serialize(std::byte *Buff) const {
99+
// Semantics followed by APInt.
100+
uint32_t SemI = V.getSemantics().toOpaqueInt();
101+
std::memcpy(Buff, &SemI, sizeof(SemI));
102+
103+
llvm::APInt API = V.getValue();
104+
llvm::StoreIntToMemory(API, (uint8_t *)(Buff + sizeof(SemI)),
105+
bitWidth() / 8);
106+
}
107+
108+
static FixedPoint deserialize(const std::byte *Buff) {
109+
auto Sem = llvm::FixedPointSemantics::getFromOpaqueInt(
110+
*reinterpret_cast<const uint32_t *>(Buff));
111+
unsigned BitWidth = Sem.getWidth();
112+
APInt I(BitWidth, 0ull, !Sem.isSigned());
113+
llvm::LoadIntFromMemory(
114+
I, reinterpret_cast<const uint8_t *>(Buff + sizeof(uint32_t)),
115+
BitWidth / CHAR_BIT);
116+
117+
return FixedPoint(I, Sem);
118+
}
119+
94120
static bool neg(const FixedPoint &A, FixedPoint *R) {
95121
bool Overflow = false;
96122
*R = FixedPoint(A.V.negate(&Overflow));

clang/lib/AST/ByteCode/Interp.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3070,6 +3070,13 @@ inline IntegralAP<true> ReadArg<IntegralAP<true>>(InterpState &S,
30703070
return I;
30713071
}
30723072

3073+
template <>
3074+
inline FixedPoint ReadArg<FixedPoint>(InterpState &S, CodePtr &OpPC) {
3075+
FixedPoint FP = FixedPoint::deserialize(*OpPC);
3076+
OpPC += align(FP.bytesToSerialize());
3077+
return FP;
3078+
}
3079+
30733080
} // namespace interp
30743081
} // namespace clang
30753082

0 commit comments

Comments
 (0)