[clang] [clang][bytecode] Fix initialing float elements from #embed (PR #154285)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 19 01:27:39 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
Fixes #<!-- -->152885
---
Full diff: https://github.com/llvm/llvm-project/pull/154285.diff
4 Files Affected:
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+20-6)
- (modified) clang/lib/AST/ByteCode/Compiler.h (+2-1)
- (modified) clang/lib/AST/ByteCode/PrimType.h (+13)
- (modified) clang/test/Preprocessor/embed_constexpr.c (+5)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index f2ce69a62838e..c86b427549609 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -1939,8 +1939,17 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
PrimType TargetT = classifyPrim(Init->getType());
auto Eval = [&](const IntegerLiteral *IL, unsigned ElemIndex) {
- if (!this->emitConst(IL->getValue(), Init))
- return false;
+ if (TargetT == PT_Float) {
+ if (!this->emitConst(IL->getValue(), classifyPrim(IL), Init))
+ return false;
+ const auto *Sem = &Ctx.getFloatSemantics(CAT->getElementType());
+ if (!this->emitCastIntegralFloating(classifyPrim(IL), Sem,
+ getFPOptions(E), E))
+ return false;
+ } else {
+ if (!this->emitConst(IL->getValue(), TargetT, Init))
+ return false;
+ }
return this->emitInitElem(TargetT, ElemIndex, IL);
};
if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
@@ -4108,8 +4117,7 @@ bool Compiler<Emitter>::VisitCXXStdInitializerListExpr(
PrimType SecondFieldT = classifyPrim(R->getField(1u)->Decl->getType());
if (isIntegralType(SecondFieldT)) {
- if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()),
- SecondFieldT, E))
+ if (!this->emitConst(ArrayType->getSize(), SecondFieldT, E))
return false;
return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
}
@@ -4119,7 +4127,7 @@ bool Compiler<Emitter>::VisitCXXStdInitializerListExpr(
return false;
if (!this->emitExpandPtr(E))
return false;
- if (!this->emitConst(static_cast<APSInt>(ArrayType->getSize()), PT_Uint64, E))
+ if (!this->emitConst(ArrayType->getSize(), PT_Uint64, E))
return false;
if (!this->emitArrayElemPtrPop(PT_Uint64, E))
return false;
@@ -4497,12 +4505,18 @@ bool Compiler<Emitter>::emitConst(T Value, const Expr *E) {
template <class Emitter>
bool Compiler<Emitter>::emitConst(const APSInt &Value, PrimType Ty,
const Expr *E) {
+ return this->emitConst(static_cast<const APInt &>(Value), Ty, E);
+}
+
+template <class Emitter>
+bool Compiler<Emitter>::emitConst(const APInt &Value, PrimType Ty,
+ const Expr *E) {
if (Ty == PT_IntAPS)
return this->emitConstIntAPS(Value, E);
if (Ty == PT_IntAP)
return this->emitConstIntAP(Value, E);
- if (Value.isSigned())
+ if (isSignedType(Ty))
return this->emitConst(Value.getSExtValue(), Ty, E);
return this->emitConst(Value.getZExtValue(), Ty, E);
}
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index 20571df0432f9..cdf587cca6634 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -347,9 +347,10 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
/// Emits an APSInt constant.
bool emitConst(const llvm::APSInt &Value, PrimType Ty, const Expr *E);
+ bool emitConst(const llvm::APInt &Value, PrimType Ty, const Expr *E);
bool emitConst(const llvm::APSInt &Value, const Expr *E);
bool emitConst(const llvm::APInt &Value, const Expr *E) {
- return emitConst(static_cast<llvm::APSInt>(Value), E);
+ return emitConst(Value, classifyPrim(E), E);
}
/// Emits an integer constant.
diff --git a/clang/lib/AST/ByteCode/PrimType.h b/clang/lib/AST/ByteCode/PrimType.h
index 093084a8aad7b..6e3a49cadcbf1 100644
--- a/clang/lib/AST/ByteCode/PrimType.h
+++ b/clang/lib/AST/ByteCode/PrimType.h
@@ -86,6 +86,19 @@ inline constexpr bool isPtrType(PrimType T) {
return T == PT_Ptr || T == PT_MemberPtr;
}
+inline constexpr bool isSignedType(PrimType T) {
+ switch (T) {
+ case PT_Sint8:
+ case PT_Sint16:
+ case PT_Sint32:
+ case PT_Sint64:
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
+
enum class CastKind : uint8_t {
Reinterpret,
Volatile,
diff --git a/clang/test/Preprocessor/embed_constexpr.c b/clang/test/Preprocessor/embed_constexpr.c
index e444dfec158b5..e4c85cce459e8 100644
--- a/clang/test/Preprocessor/embed_constexpr.c
+++ b/clang/test/Preprocessor/embed_constexpr.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%S/Inputs -verify -std=c23
+// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%S/Inputs -verify -std=c23 -fexperimental-new-constant-interpreter
static constexpr unsigned char data[] = {
#embed "big_char.txt"
@@ -19,3 +20,7 @@ static constexpr unsigned data3[] = {
static constexpr int data4[] = {
#embed "big_char.txt" suffix(, -1)
};
+
+static constexpr float data5[] = {
+#embed "big_char.txt" suffix(, -1)
+};
``````````
</details>
https://github.com/llvm/llvm-project/pull/154285
More information about the cfe-commits
mailing list