Skip to content

Commit 0fb0617

Browse files
authored
[clang][bytecode] Check vector element types for eligibility (#119385)
Like we do in ExprConstant.cpp.
1 parent 3a573dc commit 0fb0617

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,35 @@ static bool CheckBitcastType(InterpState &S, CodePtr OpPC, QualType T,
222222
IsToType))
223223
return false;
224224

225+
if (const auto *VT = T->getAs<VectorType>()) {
226+
const ASTContext &ASTCtx = S.getASTContext();
227+
QualType EltTy = VT->getElementType();
228+
unsigned NElts = VT->getNumElements();
229+
unsigned EltSize =
230+
VT->isExtVectorBoolType() ? 1 : ASTCtx.getTypeSize(EltTy);
231+
232+
if ((NElts * EltSize) % ASTCtx.getCharWidth() != 0) {
233+
// The vector's size in bits is not a multiple of the target's byte size,
234+
// so its layout is unspecified. For now, we'll simply treat these cases
235+
// as unsupported (this should only be possible with OpenCL bool vectors
236+
// whose element count isn't a multiple of the byte size).
237+
const Expr *E = S.Current->getExpr(OpPC);
238+
S.FFDiag(E, diag::note_constexpr_bit_cast_invalid_vector)
239+
<< QualType(VT, 0) << EltSize << NElts << ASTCtx.getCharWidth();
240+
return false;
241+
}
242+
243+
if (EltTy->isRealFloatingType() &&
244+
&ASTCtx.getFloatTypeSemantics(EltTy) == &APFloat::x87DoubleExtended()) {
245+
// The layout for x86_fp80 vectors seems to be handled very inconsistently
246+
// by both clang and LLVM, so for now we won't allow bit_casts involving
247+
// it in a constexpr context.
248+
const Expr *E = S.Current->getExpr(OpPC);
249+
S.FFDiag(E, diag::note_constexpr_bit_cast_unsupported_type) << EltTy;
250+
return false;
251+
}
252+
}
253+
225254
return true;
226255
}
227256

clang/test/AST/ByteCode/builtin-bit-cast.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,3 +502,8 @@ namespace OversizedBitField {
502502
// ref-note {{constexpr bit_cast involving bit-field is not yet supported}}
503503
#endif
504504
}
505+
506+
typedef bool bool9 __attribute__((ext_vector_type(9)));
507+
// both-error@+2 {{constexpr variable 'bad_bool9_to_short' must be initialized by a constant expression}}
508+
// 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}}
509+
constexpr unsigned short bad_bool9_to_short = __builtin_bit_cast(unsigned short, bool9{1,1,0,1,0,1,0,1,0});

0 commit comments

Comments
 (0)