[clang] [clang] Implement constexpr __builtin_bit_cast for complex types (PR #109981)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 25 06:47:55 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
Fixes https://github.com/llvm/llvm-project/issues/94620
---
Full diff: https://github.com/llvm/llvm-project/pull/109981.diff
2 Files Affected:
- (modified) clang/lib/AST/ExprConstant.cpp (+43)
- (modified) clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp (+8)
``````````diff
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), "");
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/109981
More information about the cfe-commits
mailing list