[clang][Interp] Handle imaginary literals (#79130)
Initialize the first element to 0 and the second element to the value of the subexpression.
This commit is contained in:
parent
5d9ffcd7f8
commit
6ff431b01e
@ -393,6 +393,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());
|
||||
@ -2883,6 +2908,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))
|
||||
|
||||
@ -61,6 +61,7 @@ public:
|
||||
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);
|
||||
|
||||
@ -111,11 +111,13 @@ 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()))
|
||||
if (!VD->getType()->isAnyComplexType() &&
|
||||
!Res.checkFullyInitialized(C.getState()))
|
||||
return false;
|
||||
|
||||
// lvalue-to-rvalue conversion.
|
||||
|
||||
@ -61,6 +61,14 @@ static_assert(__real(D3) == 1.0, "");
|
||||
static_assert(__imag(D3) == 3.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 ignored() {
|
||||
I2;
|
||||
(int)I2;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user