[clang] [clang][Interp] Implement integral->complex casts (PR #75590)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 15 07:54:59 PST 2024


https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/75590

>From 2823e9e9e32aeb2efe08e1b8b64b0fc7e8c408a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Fri, 15 Dec 2023 13:11:16 +0100
Subject: [PATCH] [clang][Interp] Implement integral->complex casts

---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 27 ++++++++++++++++++++++++
 clang/test/AST/Interp/complex.cpp        | 10 ++++-----
 2 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 5839123a5b95f2..b3d08646004405 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -290,6 +290,29 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
   case CK_ToVoid:
     return discard(SubExpr);
 
+  case CK_IntegralRealToComplex:
+  case CK_FloatingRealToComplex: {
+    // We're creating a complex value here, so we need to
+    // allocate storage for it.
+    if (!Initializing) {
+      std::optional<unsigned> LocalIndex =
+          allocateLocal(CE, /*IsExtended=*/true);
+      if (!LocalIndex)
+        return false;
+      if (!this->emitGetPtrLocal(*LocalIndex, CE))
+        return false;
+    }
+
+    // Init the complex value to {SubExpr, 0}.
+    if (!this->visitArrayElemInit(0, SubExpr))
+      return false;
+    // Zero-init the second element.
+    PrimType T = classifyPrim(SubExpr->getType());
+    if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr))
+      return false;
+    return this->emitInitElem(T, 1, SubExpr);
+  }
+
   default:
     assert(false && "Cast not implemented");
   }
@@ -842,6 +865,10 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
 
   if (T->isAnyComplexType()) {
     unsigned NumInits = E->getNumInits();
+
+    if (NumInits == 1)
+      return this->delegate(E->inits()[0]);
+
     QualType ElemQT = E->getType()->getAs<ComplexType>()->getElementType();
     PrimType ElemT = classifyPrim(ElemQT);
     if (NumInits == 0) {
diff --git a/clang/test/AST/Interp/complex.cpp b/clang/test/AST/Interp/complex.cpp
index 1e97cc61849524..3c09640cd832db 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -42,22 +42,20 @@ static_assert(__real(12u) == 12u, "");
 static_assert(__imag(4.0) == 0.0, "");
 static_assert(__imag(13) == 0, "");
 
-
+static_assert(__real((_Complex unsigned)5) == 5);
+static_assert(__imag((_Complex unsigned)5) == 0);
 
 /// Standalone complex expressions.
 static_assert(__real((_Complex float){1.0, 3.0}) == 1.0, "");
 
 
-#if 0
-/// FIXME: This should work in the new interpreter.
 constexpr _Complex double D2 = {12};
 static_assert(__real(D2) == 12, "");
-static_assert(__imag(D2) == 12, "");
+static_assert(__imag(D2) == 0, "");
 
 constexpr _Complex int I3 = {15};
 static_assert(__real(I3) == 15, "");
-static_assert(__imag(I3) == 15, "");
-#endif
+static_assert(__imag(I3) == 0, "");
 
 /// FIXME: This should work in the new interpreter as well.
 // constexpr _Complex _BitInt(8) A = 0;// = {4};



More information about the cfe-commits mailing list