[clang] [clang][Interp] Implement ComplexToReal casts (PR #77294)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 15 07:34:48 PST 2024
Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>,
Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/77294 at github.com>
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/77294
>From 5f6a91cd7f709a3c94c65dc4ea41b5967b9fe343 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 8 Jan 2024 11:14:41 +0100
Subject: [PATCH 1/3] [clang][Interp] Implement ComplexToReal casts
Add a new emitComplexReal() helper function and use that for the
new casts as well as the old __real implementation.
---
clang/lib/AST/Interp/ByteCodeExprGen.cpp | 45 ++++++++++++++++--------
clang/lib/AST/Interp/ByteCodeExprGen.h | 2 ++
clang/test/AST/Interp/complex.cpp | 15 ++++++--
3 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 5839123a5b95f2..138ffed392fcac 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -287,6 +287,10 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
return true;
}
+ case CK_IntegralComplexToReal:
+ case CK_FloatingComplexToReal:
+ return this->emitComplexReal(SubExpr);
+
case CK_ToVoid:
return discard(SubExpr);
@@ -2030,7 +2034,7 @@ bool ByteCodeExprGen<Emitter>::dereference(
}
if (LV->getType()->isAnyComplexType())
- return visit(LV);
+ return this->delegate(LV);
return false;
}
@@ -2767,22 +2771,10 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
if (!this->visit(SubExpr))
return false;
return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
- case UO_Real: { // __real x
+ case UO_Real: // __real x
if (T)
return this->delegate(SubExpr);
- if (!this->visit(SubExpr))
- return false;
- if (!this->emitConstUint8(0, E))
- return false;
- if (!this->emitArrayElemPtrPopUint8(E))
- return false;
-
- // Since our _Complex implementation does not map to a primitive type,
- // we sometimes have to do the lvalue-to-rvalue conversion here manually.
- if (!SubExpr->isLValue())
- return this->emitLoadPop(classifyPrim(E->getType()), E);
- return true;
- }
+ return this->emitComplexReal(SubExpr);
case UO_Imag: { // __imag x
if (T) {
if (!this->discard(SubExpr))
@@ -2953,6 +2945,29 @@ bool ByteCodeExprGen<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
return false;
}
+/// Emits __real(SubExpr)
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::emitComplexReal(const Expr *SubExpr) {
+ assert(SubExpr->getType()->isAnyComplexType());
+
+ if (DiscardResult)
+ return this->discard(SubExpr);
+
+ if (!this->visit(SubExpr))
+ return false;
+ if (!this->emitConstUint8(0, SubExpr))
+ return false;
+ if (!this->emitArrayElemPtrPopUint8(SubExpr))
+ return false;
+
+ // Since our _Complex implementation does not map to a primitive type,
+ // we sometimes have to do the lvalue-to-rvalue conversion here manually.
+ if (!SubExpr->isLValue())
+ return this->emitLoadPop(*classifyComplexElementType(SubExpr->getType()),
+ SubExpr);
+ return true;
+}
+
/// When calling this, we have a pointer of the local-to-destroy
/// on the stack.
/// Emit destruction of record types (or arrays of record types).
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index bbb13e97e72569..48005ce05724b5 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -294,6 +294,8 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
return this->classify(ElemType);
}
+ bool emitComplexReal(const Expr *SubExpr);
+
bool emitRecordDestruction(const Descriptor *Desc);
unsigned collectBaseOffset(const RecordType *BaseType,
const RecordType *DerivedType);
diff --git a/clang/test/AST/Interp/complex.cpp b/clang/test/AST/Interp/complex.cpp
index 1e97cc61849524..a5bc204366399a 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s
-// RUN: %clang_cc1 -verify=ref %s
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify -Wno-unused-value %s
+// RUN: %clang_cc1 -verify=ref -Wno-unused-value %s
// expected-no-diagnostics
// ref-no-diagnostics
@@ -42,6 +42,17 @@ static_assert(__real(12u) == 12u, "");
static_assert(__imag(4.0) == 0.0, "");
static_assert(__imag(13) == 0, "");
+constexpr int ignoredCast() {
+ I2;
+ (int)I2;
+ /* (float)I2; FIXME*/
+ D1;
+ /* (int)D1; FIXME*/
+ (double)D1;
+ return 0;
+}
+static_assert(ignoredCast() == 0, "");
+static_assert((int)I1 == 1, "");
/// Standalone complex expressions.
>From 85d4ffb15f466b8b2aa5d3e522ce4e449de662ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 15 Jan 2024 09:52:26 +0100
Subject: [PATCH 2/3] Enable commented-out tests
---
clang/test/AST/Interp/complex.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/AST/Interp/complex.cpp b/clang/test/AST/Interp/complex.cpp
index a5bc204366399a..7870a2a1eb5e6a 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -45,9 +45,9 @@ static_assert(__imag(13) == 0, "");
constexpr int ignoredCast() {
I2;
(int)I2;
- /* (float)I2; FIXME*/
+ (float)I2;
D1;
- /* (int)D1; FIXME*/
+ (int)D1;
(double)D1;
return 0;
}
>From 7d84c479869259ad47953ffe58f3ab7d6178addc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 15 Jan 2024 16:34:31 +0100
Subject: [PATCH 3/3] Add another test
---
clang/test/AST/Interp/complex.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/test/AST/Interp/complex.cpp b/clang/test/AST/Interp/complex.cpp
index 7870a2a1eb5e6a..e63693a0cfaa14 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -53,6 +53,7 @@ constexpr int ignoredCast() {
}
static_assert(ignoredCast() == 0, "");
static_assert((int)I1 == 1, "");
+static_assert((float)D == 1.0f, "");
/// Standalone complex expressions.
More information about the cfe-commits
mailing list