[clang] 8b4bb15 - [clang][Interp] Implement integral->complex casts (#75590)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 19 00:27:34 PST 2024
Author: Timm Baeder
Date: 2024-01-19T09:27:30+01:00
New Revision: 8b4bb15f6d879fd8655f9e41fee224a8a59f238c
URL: https://github.com/llvm/llvm-project/commit/8b4bb15f6d879fd8655f9e41fee224a8a59f238c
DIFF: https://github.com/llvm/llvm-project/commit/8b4bb15f6d879fd8655f9e41fee224a8a59f238c.diff
LOG: [clang][Interp] Implement integral->complex casts (#75590)
Allocate storage for them, initialize the first member with the given
value and the second member to 0.
Added:
Modified:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/complex.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 138ffed392fcac3..82ef743e6a78191 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -294,6 +294,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");
}
@@ -846,6 +869,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 e63693a0cfaa140..99c0dd141d0b77a 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -55,21 +55,20 @@ static_assert(ignoredCast() == 0, "");
static_assert((int)I1 == 1, "");
static_assert((float)D == 1.0f, "");
+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