-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][Interp] Handle imaginary literals #79130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesInitialize the first element to 0 and the second element to the value of the subexpression. Full diff: https://github.com/llvm/llvm-project/pull/79130.diff 4 Files Affected:
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 06518281132685..ed4cca83271aab 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 df4cb736299cb6..44446275c17a23 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 75a300bcbace1a..5961784e951fb6 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 99c0dd141d0b77..215ae571022072 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;
|
Ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM aside from a minor simplification.
✅ With the latest revision this PR passed the C/C++ code formatter. |
Initialize the first element to 0 and the second element to the value of the subexpression.
99a751f
to
db25ed3
Compare
Initialize the first element to 0 and the second element to the value of the subexpression.
Initialize the first element to 0 and the second element to the value of the subexpression.
Initialize the first element to 0 and the second element to the value of the subexpression.