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}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits