Skip to content

Commit a1039c1

Browse files
authored
[clang][bytecode] Fix initializing float elements from #embed (#154285)
Fixes #152885
1 parent 56ce40b commit a1039c1

File tree

4 files changed

+40
-7
lines changed

4 files changed

+40
-7
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,8 +1939,17 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
19391939
PrimType TargetT = classifyPrim(Init->getType());
19401940

19411941
auto Eval = [&](const IntegerLiteral *IL, unsigned ElemIndex) {
1942-
if (!this->emitConst(IL->getValue(), Init))
1943-
return false;
1942+
if (TargetT == PT_Float) {
1943+
if (!this->emitConst(IL->getValue(), classifyPrim(IL), Init))
1944+
return false;
1945+
const auto *Sem = &Ctx.getFloatSemantics(CAT->getElementType());
1946+
if (!this->emitCastIntegralFloating(classifyPrim(IL), Sem,
1947+
getFPOptions(E), E))
1948+
return false;
1949+
} else {
1950+
if (!this->emitConst(IL->getValue(), TargetT, Init))
1951+
return false;
1952+
}
19441953
return this->emitInitElem(TargetT, ElemIndex, IL);
19451954
};
19461955
if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
@@ -4108,8 +4117,7 @@ bool Compiler<Emitter>::VisitCXXStdInitializerListExpr(
41084117

41094118
PrimType SecondFieldT = classifyPrim(R->getField(1u)->Decl->getType());
41104119
if (isIntegralType(SecondFieldT)) {
4111-
if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()),
4112-
SecondFieldT, E))
4120+
if (!this->emitConst(ArrayType->getSize(), SecondFieldT, E))
41134121
return false;
41144122
return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
41154123
}
@@ -4119,7 +4127,7 @@ bool Compiler<Emitter>::VisitCXXStdInitializerListExpr(
41194127
return false;
41204128
if (!this->emitExpandPtr(E))
41214129
return false;
4122-
if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()), PT_Uint64, E))
4130+
if (!this->emitConst(ArrayType->getSize(), PT_Uint64, E))
41234131
return false;
41244132
if (!this->emitArrayElemPtrPop(PT_Uint64, E))
41254133
return false;
@@ -4497,12 +4505,18 @@ bool Compiler<Emitter>::emitConst(T Value, const Expr *E) {
44974505
template <class Emitter>
44984506
bool Compiler<Emitter>::emitConst(const APSInt &Value, PrimType Ty,
44994507
const Expr *E) {
4508+
return this->emitConst(static_cast<const APInt &>(Value), Ty, E);
4509+
}
4510+
4511+
template <class Emitter>
4512+
bool Compiler<Emitter>::emitConst(const APInt &Value, PrimType Ty,
4513+
const Expr *E) {
45004514
if (Ty == PT_IntAPS)
45014515
return this->emitConstIntAPS(Value, E);
45024516
if (Ty == PT_IntAP)
45034517
return this->emitConstIntAP(Value, E);
45044518

4505-
if (Value.isSigned())
4519+
if (isSignedType(Ty))
45064520
return this->emitConst(Value.getSExtValue(), Ty, E);
45074521
return this->emitConst(Value.getZExtValue(), Ty, E);
45084522
}

clang/lib/AST/ByteCode/Compiler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,10 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
347347

348348
/// Emits an APSInt constant.
349349
bool emitConst(const llvm::APSInt &Value, PrimType Ty, const Expr *E);
350+
bool emitConst(const llvm::APInt &Value, PrimType Ty, const Expr *E);
350351
bool emitConst(const llvm::APSInt &Value, const Expr *E);
351352
bool emitConst(const llvm::APInt &Value, const Expr *E) {
352-
return emitConst(static_cast<llvm::APSInt>(Value), E);
353+
return emitConst(Value, classifyPrim(E), E);
353354
}
354355

355356
/// Emits an integer constant.

clang/lib/AST/ByteCode/PrimType.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ inline constexpr bool isPtrType(PrimType T) {
8686
return T == PT_Ptr || T == PT_MemberPtr;
8787
}
8888

89+
inline constexpr bool isSignedType(PrimType T) {
90+
switch (T) {
91+
case PT_Sint8:
92+
case PT_Sint16:
93+
case PT_Sint32:
94+
case PT_Sint64:
95+
return true;
96+
default:
97+
return false;
98+
}
99+
return false;
100+
}
101+
89102
enum class CastKind : uint8_t {
90103
Reinterpret,
91104
Volatile,

clang/test/Preprocessor/embed_constexpr.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%S/Inputs -verify -std=c23
2+
// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%S/Inputs -verify -std=c23 -fexperimental-new-constant-interpreter
23

34
static constexpr unsigned char data[] = {
45
#embed "big_char.txt"
@@ -19,3 +20,7 @@ static constexpr unsigned data3[] = {
1920
static constexpr int data4[] = {
2021
#embed "big_char.txt" suffix(, -1)
2122
};
23+
24+
static constexpr float data5[] = {
25+
#embed "big_char.txt" suffix(, -1)
26+
};

0 commit comments

Comments
 (0)