diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3021,6 +3021,7 @@ def err_attribute_too_few_arguments : Error< "%0 attribute takes at least %1 argument%s1">; def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">; +def err_attribute_invalid_bitint_vector_type : Error<"invalid vector element type %0, must be byte-sized and power of 2 _BitInt">; def err_attribute_invalid_matrix_type : Error<"invalid matrix element type %0">; def err_attribute_bad_neon_vector_size : Error< "Neon vector size must be 64 or 128 bits">; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4012,7 +4012,11 @@ /// the specified element type and size. VectorType must be a built-in type. QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts, VectorType::VectorKind VecKind) const { - assert(vecType->isBuiltinType()); + assert(vecType->isBuiltinType() || + (vecType->isBitIntType() && + // Only support _BitInt elements with byte-sized power of 2 NumBits. + llvm::isPowerOf2_32(vecType->getAs()->getNumBits()) && + vecType->getAs()->getNumBits() >= 8)); // Check if we've already instantiated a vector of this type. llvm::FoldingSetNodeID ID; @@ -4080,9 +4084,13 @@ /// getExtVectorType - Return the unique reference to an extended vector type of /// the specified element type and size. VectorType must be a built-in type. -QualType -ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) const { - assert(vecType->isBuiltinType() || vecType->isDependentType()); +QualType ASTContext::getExtVectorType(QualType vecType, + unsigned NumElts) const { + assert(vecType->isBuiltinType() || vecType->isDependentType() || + (vecType->isBitIntType() && + // Only support _BitInt elements with byte-sized power of 2 NumBits. + llvm::isPowerOf2_32(vecType->getAs()->getNumBits()) && + vecType->getAs()->getNumBits() >= 8)); // Check if we've already instantiated a vector of this type. llvm::FoldingSetNodeID ID; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2637,11 +2637,20 @@ // can't already be a vector. if ((!CurType->isDependentType() && (!CurType->isBuiltinType() || CurType->isBooleanType() || - (!CurType->isIntegerType() && !CurType->isRealFloatingType()))) || + (!CurType->isIntegerType() && !CurType->isRealFloatingType())) && + !CurType->isBitIntType()) || CurType->isArrayType()) { Diag(AttrLoc, diag::err_attribute_invalid_vector_type) << CurType; return QualType(); } + // Only support _BitInt elements with byte-sized power of 2 NumBits. + if (CurType->isBitIntType()) { + unsigned NumBits = CurType->getAs()->getNumBits(); + if (!llvm::isPowerOf2_32(NumBits) || NumBits < 8) { + Diag(AttrLoc, diag::err_attribute_invalid_bitint_vector_type) << CurType; + return QualType(); + } + } if (SizeExpr->isTypeDependent() || SizeExpr->isValueDependent()) return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc, @@ -2707,12 +2716,21 @@ // We explictly allow bool elements in ext_vector_type for C/C++. bool IsNoBoolVecLang = getLangOpts().OpenCL || getLangOpts().OpenCLCPlusPlus; if ((!T->isDependentType() && !T->isIntegerType() && - !T->isRealFloatingType()) || T->isBitIntType() || + !T->isRealFloatingType()) || (IsNoBoolVecLang && T->isBooleanType())) { Diag(AttrLoc, diag::err_attribute_invalid_vector_type) << T; return QualType(); } + // Only support _BitInt elements with byte-sized power of 2 NumBits. + if (T->isBitIntType()) { + unsigned NumBits = T->getAs()->getNumBits(); + if (!llvm::isPowerOf2_32(NumBits) || NumBits < 8) { + Diag(AttrLoc, diag::err_attribute_invalid_bitint_vector_type) << T; + return QualType(); + } + } + if (!ArraySize->isTypeDependent() && !ArraySize->isValueDependent()) { Optional vecSize = ArraySize->getIntegerConstantExpr(Context); if (!vecSize) { diff --git a/clang/test/Sema/builtin-classify-type.c b/clang/test/Sema/builtin-classify-type.c --- a/clang/test/Sema/builtin-classify-type.c +++ b/clang/test/Sema/builtin-classify-type.c @@ -29,6 +29,23 @@ __attribute__((vector_size(16))) int vec; typedef __attribute__((ext_vector_type(4))) int evec_t; evec_t evec; + typedef _BitInt(8) int8_t3 __attribute__((ext_vector_type(3))); + int8_t3 t3; + typedef _BitInt(16) int16_t3 __attribute__((ext_vector_type(4))); + int16_t3 t4; + typedef _BitInt(32) int32_t3 __attribute__((ext_vector_type(5))); + int32_t3 t5; + typedef _BitInt(64) int64_t3 __attribute__((ext_vector_type(6))); + int64_t3 t6; + typedef _BitInt(8) vint8_t3 __attribute__((vector_size(3))); + vint8_t3 vt3; + typedef _BitInt(16) vint16_t3 __attribute__((vector_size(4))); + vint16_t3 vt4; + typedef _BitInt(32) vint32_t3 __attribute__((vector_size(8))); + vint32_t3 vt5; + typedef _BitInt(64) vint64_t3 __attribute__((vector_size(16))); + vint64_t3 vt6; + _Atomic int atomic_i; _Atomic double atomic_d; _Complex int complex_i; diff --git a/clang/test/SemaCXX/ext-int.cpp b/clang/test/SemaCXX/ext-int.cpp --- a/clang/test/SemaCXX/ext-int.cpp +++ b/clang/test/SemaCXX/ext-int.cpp @@ -84,10 +84,22 @@ }; // Reject vector types: -// expected-error@+1{{invalid vector element type '_BitInt(32)'}} -typedef _BitInt(32) __attribute__((vector_size(16))) VecTy; -// expected-error@+1{{invalid vector element type '_BitInt(32)'}} -typedef _BitInt(32) __attribute__((ext_vector_type(32))) OtherVecTy; +// expected-error@+1{{invalid vector element type '_BitInt(2)', must be byte-sized and power of 2 _BitInt}} +typedef _BitInt(2) __attribute__((vector_size(16))) VecTy; +// expected-error@+1{{invalid vector element type '_BitInt(2)', must be byte-sized and power of 2 _BitInt}} +typedef _BitInt(2) __attribute__((ext_vector_type(32))) OtherVecTy; +// expected-error@+1{{invalid vector element type '_BitInt(4)', must be byte-sized and power of 2 _BitInt}} +typedef _BitInt(4) __attribute__((vector_size(16))) VecTy2; +// expected-error@+1{{invalid vector element type '_BitInt(4)', must be byte-sized and power of 2 _BitInt}} +typedef _BitInt(4) __attribute__((ext_vector_type(32))) OtherVecTy2; +// expected-error@+1{{invalid vector element type '_BitInt(5)', must be byte-sized and power of 2 _BitInt}} +typedef _BitInt(5) __attribute__((vector_size(16))) VecTy3; +// expected-error@+1{{invalid vector element type '_BitInt(5)', must be byte-sized and power of 2 _BitInt}} +typedef _BitInt(5) __attribute__((ext_vector_type(32))) OtherVecTy3; +// expected-error@+1{{invalid vector element type '_BitInt(37)', must be byte-sized and power of 2 _BitInt}} +typedef _BitInt(37) __attribute__((vector_size(16))) VecTy4; +// expected-error@+1{{invalid vector element type '_BitInt(37)', must be byte-sized and power of 2 _BitInt}} +typedef _BitInt(37) __attribute__((ext_vector_type(32))) OtherVecTy4; // Allow _Complex: _Complex _BitInt(3) Cmplx;