[clang] 6ff431b - [clang][Interp] Handle imaginary literals (#79130)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 31 22:13:14 PST 2024


Author: Timm Baeder
Date: 2024-02-01T07:13:10+01:00
New Revision: 6ff431b01e29e99c7dbfcda96bdefdff91dcdf7f

URL: https://github.com/llvm/llvm-project/commit/6ff431b01e29e99c7dbfcda96bdefdff91dcdf7f
DIFF: https://github.com/llvm/llvm-project/commit/6ff431b01e29e99c7dbfcda96bdefdff91dcdf7f.diff

LOG: [clang][Interp] Handle imaginary literals (#79130)

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

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/lib/AST/Interp/ByteCodeExprGen.h
    clang/lib/AST/Interp/Context.cpp
    clang/test/AST/Interp/complex.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index d307739c301ef..c0721b0daf9a3 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -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))

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 315169d487cd4..971fd09bdfac5 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 ba80a015965b3..5f5a6622f10f3 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -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.

diff  --git a/clang/test/AST/Interp/complex.cpp b/clang/test/AST/Interp/complex.cpp
index bb230c2ebe64d..fdd1d738de828 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -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;


        


More information about the cfe-commits mailing list