Skip to content

Commit 6ff431b

Browse files
authored
[clang][Interp] Handle imaginary literals (#79130)
Initialize the first element to 0 and the second element to the value of the subexpression.
1 parent 5d9ffcd commit 6ff431b

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,31 @@ bool ByteCodeExprGen<Emitter>::VisitFloatingLiteral(const FloatingLiteral *E) {
393393
return this->emitConstFloat(E->getValue(), E);
394394
}
395395

396+
template <class Emitter>
397+
bool ByteCodeExprGen<Emitter>::VisitImaginaryLiteral(
398+
const ImaginaryLiteral *E) {
399+
assert(E->getType()->isAnyComplexType());
400+
if (DiscardResult)
401+
return true;
402+
403+
if (!Initializing) {
404+
std::optional<unsigned> LocalIndex = allocateLocal(E, /*IsExtended=*/false);
405+
if (!LocalIndex)
406+
return false;
407+
if (!this->emitGetPtrLocal(*LocalIndex, E))
408+
return false;
409+
}
410+
411+
const Expr *SubExpr = E->getSubExpr();
412+
PrimType SubExprT = classifyPrim(SubExpr->getType());
413+
414+
if (!this->visitZeroInitializer(SubExprT, SubExpr->getType(), SubExpr))
415+
return false;
416+
if (!this->emitInitElem(SubExprT, 0, SubExpr))
417+
return false;
418+
return this->visitArrayElemInit(1, SubExpr);
419+
}
420+
396421
template <class Emitter>
397422
bool ByteCodeExprGen<Emitter>::VisitParenExpr(const ParenExpr *E) {
398423
return this->delegate(E->getSubExpr());
@@ -2883,6 +2908,7 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
28832908
return false;
28842909
return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
28852910
}
2911+
28862912
if (!this->visit(SubExpr))
28872913
return false;
28882914
if (!this->emitConstUint8(1, E))

clang/lib/AST/Interp/ByteCodeExprGen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
6161
bool VisitCastExpr(const CastExpr *E);
6262
bool VisitIntegerLiteral(const IntegerLiteral *E);
6363
bool VisitFloatingLiteral(const FloatingLiteral *E);
64+
bool VisitImaginaryLiteral(const ImaginaryLiteral *E);
6465
bool VisitParenExpr(const ParenExpr *E);
6566
bool VisitBinaryOperator(const BinaryOperator *E);
6667
bool VisitLogicalBinOp(const BinaryOperator *E);

clang/lib/AST/Interp/Context.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,13 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,
111111
#endif
112112

113113
// Ensure global variables are fully initialized.
114-
if (shouldBeGloballyIndexed(VD) && !Res.isInvalid() &&
115-
(VD->getType()->isRecordType() || VD->getType()->isArrayType())) {
114+
if (shouldBeGloballyIndexed(VD) &&
115+
(VD->getType()->isRecordType() || VD->getType()->isArrayType() ||
116+
VD->getType()->isAnyComplexType())) {
116117
assert(Res.isLValue());
117118

118-
if (!Res.checkFullyInitialized(C.getState()))
119+
if (!VD->getType()->isAnyComplexType() &&
120+
!Res.checkFullyInitialized(C.getState()))
119121
return false;
120122

121123
// lvalue-to-rvalue conversion.

clang/test/AST/Interp/complex.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ static_assert(__real(D3) == 1.0, "");
6161
static_assert(__imag(D3) == 3.0, "");
6262

6363

64+
constexpr _Complex int a = 2i;
65+
static_assert(__real(a) == 0, "");
66+
static_assert(__imag(a) == 2, "");
67+
68+
constexpr _Complex double b = 4.0i;
69+
static_assert(__real(b) == 0, "");
70+
static_assert(__imag(b) == 4, "");
71+
6472
constexpr int ignored() {
6573
I2;
6674
(int)I2;

0 commit comments

Comments
 (0)