Timm =?utf-8?q?Bäder?= <tbae...@redhat.com> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/77...@github.com>
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/77294 >From 4c9d611f5ae8cbad083811261e08954d92b0ca41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Mon, 8 Jan 2024 11:14:41 +0100 Subject: [PATCH 1/2] [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 | 16 +++++++-- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 7f8bbe787324814..ef28673013e12d1 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,21 +2771,9 @@ 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 assert(!T); - 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 assert(!T); if (!this->visit(SubExpr)) @@ -2948,6 +2940,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 bbb13e97e725692..48005ce05724b54 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 66490e973988bb5..fd5cb8395550b55 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 @@ -37,6 +37,18 @@ constexpr _Complex int I2 = {}; static_assert(__real(I2) == 0, ""); static_assert(__imag(I2) == 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. static_assert(__real((_Complex float){1.0, 3.0}) == 1.0, ""); >From 95b1c77ecbde52162a5a80282176f693031c1322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Mon, 15 Jan 2024 09:52:26 +0100 Subject: [PATCH 2/2] 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 fd5cb8395550b55..3b288268d6c5485 100644 --- a/clang/test/AST/Interp/complex.cpp +++ b/clang/test/AST/Interp/complex.cpp @@ -40,9 +40,9 @@ static_assert(__imag(I2) == 0, ""); constexpr int ignoredCast() { I2; (int)I2; - /* (float)I2; FIXME*/ + (float)I2; D1; - /* (int)D1; FIXME*/ + (int)D1; (double)D1; return 0; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits