Author: Timm Baeder
Date: 2025-08-19T11:04:21+02:00
New Revision: a1039c1b841853f42eb85f0ad4f368b5b2565cca

URL: 
https://github.com/llvm/llvm-project/commit/a1039c1b841853f42eb85f0ad4f368b5b2565cca
DIFF: 
https://github.com/llvm/llvm-project/commit/a1039c1b841853f42eb85f0ad4f368b5b2565cca.diff

LOG: [clang][bytecode] Fix initializing float elements from #embed (#154285)

Fixes #152885

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Compiler.cpp
    clang/lib/AST/ByteCode/Compiler.h
    clang/lib/AST/ByteCode/PrimType.h
    clang/test/Preprocessor/embed_constexpr.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index f7947bd8a3797..e9d937fa632cf 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)
+};


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to