https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/79130
Initialize the first element to 0 and the second element to the value of the subexpression. >From 34f0c1b9297bd817f8aaf9ddcb29457fa5e96aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Tue, 23 Jan 2024 09:14:02 +0100 Subject: [PATCH] [clang][Interp] Handle imaginary literals Initialize the first element to 0 and the second element to the value of the subexpression. --- clang/lib/AST/Interp/ByteCodeExprGen.cpp | 26 ++++++++++++++++++++++++ clang/lib/AST/Interp/ByteCodeExprGen.h | 1 + clang/lib/AST/Interp/Context.cpp | 11 ++++++---- clang/test/AST/Interp/complex.cpp | 9 ++++++++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 065182811326859..ed4cca83271aab0 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -339,6 +339,31 @@ bool ByteCodeExprGen<Emitter>::VisitFloatingLiteral(const FloatingLiteral *E) { return this->emitConstFloat(E->getValue(), E); } +template <class Emitter> +bool ByteCodeExprGen<Emitter>::VisitImaginaryLiteral( + const ImaginaryLiteral *E) { + assert(E->getType()->isAnyComplexType()); + if (DiscardResult) + return true; + + if (!Initializing) { + std::optional<unsigned> LocalIndex = allocateLocal(E, /*IsExtended=*/false); + if (!LocalIndex) + return false; + if (!this->emitGetPtrLocal(*LocalIndex, E)) + return false; + } + + const Expr *SubExpr = E->getSubExpr(); + PrimType SubExprT = classifyPrim(SubExpr->getType()); + + if (!this->visitZeroInitializer(SubExprT, SubExpr->getType(), SubExpr)) + return false; + if (!this->emitInitElem(SubExprT, 0, SubExpr)) + return false; + return this->visitArrayElemInit(1, SubExpr); +} + template <class Emitter> bool ByteCodeExprGen<Emitter>::VisitParenExpr(const ParenExpr *E) { return this->delegate(E->getSubExpr()); @@ -2810,6 +2835,7 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { return false; return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr); } + if (!this->visit(SubExpr)) return false; if (!this->emitConstUint8(1, E)) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index df4cb736299cb62..44446275c17a231 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -61,6 +61,7 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>, bool VisitCastExpr(const CastExpr *E); bool VisitIntegerLiteral(const IntegerLiteral *E); bool VisitFloatingLiteral(const FloatingLiteral *E); + bool VisitImaginaryLiteral(const ImaginaryLiteral *E); bool VisitParenExpr(const ParenExpr *E); bool VisitBinaryOperator(const BinaryOperator *E); bool VisitLogicalBinOp(const BinaryOperator *E); diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp index 75a300bcbace1a0..5961784e951fb65 100644 --- a/clang/lib/AST/Interp/Context.cpp +++ b/clang/lib/AST/Interp/Context.cpp @@ -112,12 +112,15 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, #endif // Ensure global variables are fully initialized. - if (shouldBeGloballyIndexed(VD) && !Res.isInvalid() && - (VD->getType()->isRecordType() || VD->getType()->isArrayType())) { + if (shouldBeGloballyIndexed(VD) && + (VD->getType()->isRecordType() || VD->getType()->isArrayType() || + VD->getType()->isAnyComplexType())) { assert(Res.isLValue()); - if (!Res.checkFullyInitialized(C.getState())) - return false; + if (!VD->getType()->isAnyComplexType()) { + if (!Res.checkFullyInitialized(C.getState())) + return false; + } // lvalue-to-rvalue conversion. std::optional<APValue> RValueResult = Res.toRValue(); diff --git a/clang/test/AST/Interp/complex.cpp b/clang/test/AST/Interp/complex.cpp index 99c0dd141d0b77a..215ae5710220723 100644 --- a/clang/test/AST/Interp/complex.cpp +++ b/clang/test/AST/Interp/complex.cpp @@ -42,6 +42,15 @@ static_assert(__real(12u) == 12u, ""); static_assert(__imag(4.0) == 0.0, ""); static_assert(__imag(13) == 0, ""); + +constexpr _Complex int a = 2i; +static_assert(__real(a) == 0, ""); +static_assert(__imag(a) == 2, ""); + +constexpr _Complex double b = 4.0i; +static_assert(__real(b) == 0, ""); +static_assert(__imag(b) == 4, ""); + constexpr int ignoredCast() { I2; (int)I2; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits