[clang] [clang][bytecode] Check vector element types for eligibility (PR #119385)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 10 06:14:29 PST 2024
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/119385
Like we do in ExprConstant.cpp.
>From 003dd9075216766af2b717e5cfd5f38fba15d6ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 10 Dec 2024 15:12:28 +0100
Subject: [PATCH] [clang][bytecode] Check vector element types for eligibility
Like we do in ExprConstant.cpp.
---
.../lib/AST/ByteCode/InterpBuiltinBitCast.cpp | 29 +++++++++++++++++++
clang/test/AST/ByteCode/builtin-bit-cast.cpp | 5 ++++
2 files changed, 34 insertions(+)
diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
index c9cd113287557b..7ba0faff252530 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
@@ -222,6 +222,35 @@ static bool CheckBitcastType(InterpState &S, CodePtr OpPC, QualType T,
IsToType))
return false;
+ if (const auto *VT = T->getAs<VectorType>()) {
+ const ASTContext &ASTCtx = S.getASTContext();
+ QualType EltTy = VT->getElementType();
+ unsigned NElts = VT->getNumElements();
+ unsigned EltSize =
+ VT->isExtVectorBoolType() ? 1 : ASTCtx.getTypeSize(EltTy);
+
+ if ((NElts * EltSize) % ASTCtx.getCharWidth() != 0) {
+ // The vector's size in bits is not a multiple of the target's byte size,
+ // so its layout is unspecified. For now, we'll simply treat these cases
+ // as unsupported (this should only be possible with OpenCL bool vectors
+ // whose element count isn't a multiple of the byte size).
+ const Expr *E = S.Current->getExpr(OpPC);
+ S.FFDiag(E, diag::note_constexpr_bit_cast_invalid_vector)
+ << QualType(VT, 0) << EltSize << NElts << ASTCtx.getCharWidth();
+ return false;
+ }
+
+ if (EltTy->isRealFloatingType() &&
+ &ASTCtx.getFloatTypeSemantics(EltTy) == &APFloat::x87DoubleExtended()) {
+ // The layout for x86_fp80 vectors seems to be handled very inconsistently
+ // by both clang and LLVM, so for now we won't allow bit_casts involving
+ // it in a constexpr context.
+ const Expr *E = S.Current->getExpr(OpPC);
+ S.FFDiag(E, diag::note_constexpr_bit_cast_unsupported_type) << EltTy;
+ return false;
+ }
+ }
+
return true;
}
diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
index e99ab3904c339c..8a5bef635b8fde 100644
--- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp
+++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
@@ -502,3 +502,8 @@ namespace OversizedBitField {
// ref-note {{constexpr bit_cast involving bit-field is not yet supported}}
#endif
}
+
+typedef bool bool9 __attribute__((ext_vector_type(9)));
+// both-error at +2 {{constexpr variable 'bad_bool9_to_short' must be initialized by a constant expression}}
+// both-note at +1 {{bit_cast involving type 'bool __attribute__((ext_vector_type(9)))' (vector of 9 'bool' values) is not allowed in a constant expression; element size 1 * element count 9 is not a multiple of the byte size 8}}
+constexpr unsigned short bad_bool9_to_short = __builtin_bit_cast(unsigned short, bool9{1,1,0,1,0,1,0,1,0});
More information about the cfe-commits
mailing list