https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/109981
Fixes https://github.com/llvm/llvm-project/issues/94620 >From 12f625a2c7cf39285eac05f9aa294f3017931c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Wed, 25 Sep 2024 15:45:06 +0200 Subject: [PATCH] [clang] Implement constexpr __builtin_bit_cast for complex types Fixes https://github.com/llvm/llvm-project/issues/94620 --- clang/lib/AST/ExprConstant.cpp | 43 +++++++++++++++++++ .../SemaCXX/constexpr-builtin-bit-cast.cpp | 8 ++++ 2 files changed, 51 insertions(+) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6387e375dda79c..86e956e6ea619a 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -7148,6 +7148,7 @@ class APValueToBufferConverter { case APValue::ComplexInt: case APValue::ComplexFloat: + return visitComplex(Val, Ty, Offset); case APValue::FixedPoint: // FIXME: We should support these. @@ -7234,6 +7235,31 @@ class APValueToBufferConverter { return true; } + bool visitComplex(const APValue &Val, QualType Ty, CharUnits Offset) { + const ComplexType *ComplexTy = Ty->castAs<ComplexType>(); + QualType EltTy = ComplexTy->getElementType(); + CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy); + bool IsInt = Val.isComplexInt(); + + if (IsInt) { + if (!visitInt(Val.getComplexIntReal(), EltTy, + Offset + (0 * EltSizeChars))) + return false; + if (!visitInt(Val.getComplexIntImag(), EltTy, + Offset + (1 * EltSizeChars))) + return false; + } else { + if (!visitFloat(Val.getComplexFloatReal(), EltTy, + Offset + (0 * EltSizeChars))) + return false; + if (!visitFloat(Val.getComplexFloatImag(), EltTy, + Offset + (1 * EltSizeChars))) + return false; + } + + return true; + } + bool visitVector(const APValue &Val, QualType Ty, CharUnits Offset) { const VectorType *VTy = Ty->castAs<VectorType>(); QualType EltTy = VTy->getElementType(); @@ -7506,6 +7532,23 @@ class BufferToAPValueConverter { return ArrayValue; } + std::optional<APValue> visit(const ComplexType *Ty, CharUnits Offset) { + QualType ElementType = Ty->getElementType(); + CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType); + bool IsInt = ElementType->isIntegerType(); + + std::optional<APValue> Values[2]; + for (unsigned I = 0; I != 2; ++I) { + Values[I] = visitType(Ty->getElementType(), Offset + I * ElementWidth); + if (!Values[I]) + return std::nullopt; + } + + if (IsInt) + return APValue(Values[0]->getInt(), Values[1]->getInt()); + return APValue(Values[0]->getFloat(), Values[1]->getFloat()); + } + std::optional<APValue> visit(const VectorType *VTy, CharUnits Offset) { QualType EltTy = VTy->getElementType(); unsigned NElts = VTy->getNumElements(); diff --git a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp index 7520b43a194aba..5a35a8dfdbd9a4 100644 --- a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp +++ b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp @@ -511,3 +511,11 @@ constexpr bool9 bad_short_to_bool9 = __builtin_bit_cast(bool9, static_cast<unsig constexpr bool17 bad_int_to_bool17 = __builtin_bit_cast(bool17, 0x0001CAFEU); } + +namespace test_complex { + constexpr _Complex unsigned test_int_complex = { 0x0C05FEFE, 0xCAFEBABE }; + static_assert(round_trip<_Complex unsigned>(0xCAFEBABE0C05FEFEULL), ""); + static_assert(bit_cast<unsigned long long>(test_int_complex) == (LITTLE_END + ? 0xCAFEBABE0C05FEFE + : 0x0C05FEFECAFEBABE), ""); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits