Skip to content

[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

Merged
merged 1 commit into from
Feb 1, 2024
Merged

Conversation

tbaederr
Copy link
Contributor

Initialize the first element to 0 and the second element to the value of the subexpression.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jan 23, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 23, 2024

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

Initialize 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:

  • (modified) clang/lib/AST/Interp/ByteCodeExprGen.cpp (+26)
  • (modified) clang/lib/AST/Interp/ByteCodeExprGen.h (+1)
  • (modified) clang/lib/AST/Interp/Context.cpp (+7-4)
  • (modified) clang/test/AST/Interp/complex.cpp (+9)
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;

@tbaederr
Copy link
Contributor Author

Ping

Copy link
Collaborator

@AaronBallman AaronBallman left a 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.

Copy link

github-actions bot commented Jan 31, 2024

✅ 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.
@tbaederr tbaederr merged commit 6ff431b into llvm:main Feb 1, 2024
carlosgalvezp pushed a commit to carlosgalvezp/llvm-project that referenced this pull request Feb 1, 2024
Initialize the first element to 0 and the second element to the value of
the subexpression.
agozillon pushed a commit to agozillon/llvm-project that referenced this pull request Feb 5, 2024
Initialize the first element to 0 and the second element to the value of
the subexpression.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants