Author: Timm Baeder Date: 2024-12-10T17:56:48+01:00 New Revision: 0fb06172f14110daa45bed8ae4c153967c9365dc
URL: https://github.com/llvm/llvm-project/commit/0fb06172f14110daa45bed8ae4c153967c9365dc DIFF: https://github.com/llvm/llvm-project/commit/0fb06172f14110daa45bed8ae4c153967c9365dc.diff LOG: [clang][bytecode] Check vector element types for eligibility (#119385) Like we do in ExprConstant.cpp. Added: Modified: clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp clang/test/AST/ByteCode/builtin-bit-cast.cpp Removed: ################################################################################ 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@+2 {{constexpr variable 'bad_bool9_to_short' must be initialized by a constant expression}} +// both-note@+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}); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits