Skip to content

Commit 8b4bb15

Browse files
authored
[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.
1 parent 508c6aa commit 8b4bb15

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,29 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
294294
case CK_ToVoid:
295295
return discard(SubExpr);
296296

297+
case CK_IntegralRealToComplex:
298+
case CK_FloatingRealToComplex: {
299+
// We're creating a complex value here, so we need to
300+
// allocate storage for it.
301+
if (!Initializing) {
302+
std::optional<unsigned> LocalIndex =
303+
allocateLocal(CE, /*IsExtended=*/true);
304+
if (!LocalIndex)
305+
return false;
306+
if (!this->emitGetPtrLocal(*LocalIndex, CE))
307+
return false;
308+
}
309+
310+
// Init the complex value to {SubExpr, 0}.
311+
if (!this->visitArrayElemInit(0, SubExpr))
312+
return false;
313+
// Zero-init the second element.
314+
PrimType T = classifyPrim(SubExpr->getType());
315+
if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr))
316+
return false;
317+
return this->emitInitElem(T, 1, SubExpr);
318+
}
319+
297320
default:
298321
assert(false && "Cast not implemented");
299322
}
@@ -846,6 +869,10 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
846869

847870
if (T->isAnyComplexType()) {
848871
unsigned NumInits = E->getNumInits();
872+
873+
if (NumInits == 1)
874+
return this->delegate(E->inits()[0]);
875+
849876
QualType ElemQT = E->getType()->getAs<ComplexType>()->getElementType();
850877
PrimType ElemT = classifyPrim(ElemQT);
851878
if (NumInits == 0) {

clang/test/AST/Interp/complex.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,20 @@ static_assert(ignoredCast() == 0, "");
5555
static_assert((int)I1 == 1, "");
5656
static_assert((float)D == 1.0f, "");
5757

58+
static_assert(__real((_Complex unsigned)5) == 5);
59+
static_assert(__imag((_Complex unsigned)5) == 0);
5860

5961
/// Standalone complex expressions.
6062
static_assert(__real((_Complex float){1.0, 3.0}) == 1.0, "");
6163

6264

63-
#if 0
64-
/// FIXME: This should work in the new interpreter.
6565
constexpr _Complex double D2 = {12};
6666
static_assert(__real(D2) == 12, "");
67-
static_assert(__imag(D2) == 12, "");
67+
static_assert(__imag(D2) == 0, "");
6868

6969
constexpr _Complex int I3 = {15};
7070
static_assert(__real(I3) == 15, "");
71-
static_assert(__imag(I3) == 15, "");
72-
#endif
71+
static_assert(__imag(I3) == 0, "");
7372

7473
/// FIXME: This should work in the new interpreter as well.
7574
// constexpr _Complex _BitInt(8) A = 0;// = {4};

0 commit comments

Comments
 (0)