diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 3818349901a1..4e4558479aae 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -839,66 +839,95 @@ void InitListChecker::CheckVectorType(const InitializedEntity &Entity, unsigned &Index, InitListExpr *StructuredList, unsigned &StructuredIndex) { - if (Index < IList->getNumInits()) { - const VectorType *VT = DeclType->getAs(); - unsigned maxElements = VT->getNumElements(); - unsigned numEltsInit = 0; - QualType elementType = VT->getElementType(); + if (Index >= IList->getNumInits()) + return; - if (!SemaRef.getLangOptions().OpenCL) { - InitializedEntity ElementEntity = - InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); + const VectorType *VT = DeclType->getAs(); + unsigned maxElements = VT->getNumElements(); + unsigned numEltsInit = 0; + QualType elementType = VT->getElementType(); - for (unsigned i = 0; i < maxElements; ++i, ++numEltsInit) { - // Don't attempt to go past the end of the init list - if (Index >= IList->getNumInits()) - break; - - ElementEntity.setElementIndex(Index); - CheckSubElementType(ElementEntity, IList, elementType, Index, - StructuredList, StructuredIndex); - } - } else { - InitializedEntity ElementEntity = - InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); + if (!SemaRef.getLangOptions().OpenCL) { + // If the initializing element is a vector, try to copy-initialize + // instead of breaking it apart (which is doomed to failure anyway). + Expr *Init = IList->getInit(Index); + if (!isa(Init) && Init->getType()->isVectorType()) { + ExprResult Result = + SemaRef.PerformCopyInitialization(Entity, Init->getLocStart(), + SemaRef.Owned(Init)); + + Expr *ResultExpr = 0; + if (Result.isInvalid()) + hadError = true; // types weren't compatible. + else { + ResultExpr = Result.takeAs(); - // OpenCL initializers allows vectors to be constructed from vectors. - for (unsigned i = 0; i < maxElements; ++i) { - // Don't attempt to go past the end of the init list - if (Index >= IList->getNumInits()) - break; - - ElementEntity.setElementIndex(Index); - - QualType IType = IList->getInit(Index)->getType(); - if (!IType->isVectorType()) { - CheckSubElementType(ElementEntity, IList, elementType, Index, - StructuredList, StructuredIndex); - ++numEltsInit; - } else { - QualType VecType; - const VectorType *IVT = IType->getAs(); - unsigned numIElts = IVT->getNumElements(); - - if (IType->isExtVectorType()) - VecType = SemaRef.Context.getExtVectorType(elementType, numIElts); - else - VecType = SemaRef.Context.getVectorType(elementType, numIElts, - IVT->getAltiVecSpecific()); - CheckSubElementType(ElementEntity, IList, VecType, Index, - StructuredList, StructuredIndex); - numEltsInit += numIElts; + if (ResultExpr != Init) { + // The type was promoted, update initializer list. + IList->setInit(Index, ResultExpr); } } + if (hadError) + ++StructuredIndex; + else + UpdateStructuredListElement(StructuredList, StructuredIndex, ResultExpr); + ++Index; + return; } - // OpenCL requires all elements to be initialized. - if (numEltsInit != maxElements) - if (SemaRef.getLangOptions().OpenCL) - SemaRef.Diag(IList->getSourceRange().getBegin(), - diag::err_vector_incorrect_num_initializers) - << (numEltsInit < maxElements) << maxElements << numEltsInit; + InitializedEntity ElementEntity = + InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); + + for (unsigned i = 0; i < maxElements; ++i, ++numEltsInit) { + // Don't attempt to go past the end of the init list + if (Index >= IList->getNumInits()) + break; + + ElementEntity.setElementIndex(Index); + CheckSubElementType(ElementEntity, IList, elementType, Index, + StructuredList, StructuredIndex); + } + return; } + + InitializedEntity ElementEntity = + InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); + + // OpenCL initializers allows vectors to be constructed from vectors. + for (unsigned i = 0; i < maxElements; ++i) { + // Don't attempt to go past the end of the init list + if (Index >= IList->getNumInits()) + break; + + ElementEntity.setElementIndex(Index); + + QualType IType = IList->getInit(Index)->getType(); + if (!IType->isVectorType()) { + CheckSubElementType(ElementEntity, IList, elementType, Index, + StructuredList, StructuredIndex); + ++numEltsInit; + } else { + QualType VecType; + const VectorType *IVT = IType->getAs(); + unsigned numIElts = IVT->getNumElements(); + + if (IType->isExtVectorType()) + VecType = SemaRef.Context.getExtVectorType(elementType, numIElts); + else + VecType = SemaRef.Context.getVectorType(elementType, numIElts, + IVT->getAltiVecSpecific()); + CheckSubElementType(ElementEntity, IList, VecType, Index, + StructuredList, StructuredIndex); + numEltsInit += numIElts; + } + } + + // OpenCL requires all elements to be initialized. + if (numEltsInit != maxElements) + if (SemaRef.getLangOptions().OpenCL) + SemaRef.Diag(IList->getSourceRange().getBegin(), + diag::err_vector_incorrect_num_initializers) + << (numEltsInit < maxElements) << maxElements << numEltsInit; } void InitListChecker::CheckArrayType(const InitializedEntity &Entity, diff --git a/clang/test/Sema/vector-init.c b/clang/test/Sema/vector-init.c index 8f81adc05ba3..5be040ae6c11 100644 --- a/clang/test/Sema/vector-init.c +++ b/clang/test/Sema/vector-init.c @@ -33,3 +33,12 @@ __attribute__((vector_size(16))) float f2( typedef float __attribute__((ext_vector_type (3))) float3; int test2[sizeof(float3) == sizeof(float4) ? 1 : -1]; +// rdar://problem/8345836 +typedef long long __attribute__((vector_size(16))) longlong2; +typedef short __attribute__((vector_size(16))) short8; +typedef short __attribute__((vector_size(8))) short4; +void test3() { + extern short8 test3_helper(void); + longlong2 arr1[2] = { test3_helper(), test3_helper() }; + short4 arr2[2] = { test3_helper(), test3_helper() }; // expected-error 2 {{initializing 'short4' with an expression of incompatible type 'short8'}} +}