diff options
author | John McCall <rjmccall@apple.com> | 2010-10-30 00:11:39 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-10-30 00:11:39 +0000 |
commit | 20e047abc5f19dc948436c0fb891450d9cd40667 (patch) | |
tree | 851b728936e476102f9b3ae7eeb6e32e9fc0c64b /lib/Sema/SemaInit.cpp | |
parent | 978e3a274aae203a6c2b74094be791ac9e2662e5 (diff) |
When list-initializing a vector, try to copy-initialize from vectors instead
of descending into the subelements.
rdar://problem/8345836
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117749 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 135 |
1 files changed, 82 insertions, 53 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 3818349901..4e4558479a 100644 --- a/lib/Sema/SemaInit.cpp +++ b/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<VectorType>(); - unsigned maxElements = VT->getNumElements(); - unsigned numEltsInit = 0; - QualType elementType = VT->getElementType(); - - if (!SemaRef.getLangOptions().OpenCL) { - 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); + if (Index >= IList->getNumInits()) + return; + + const VectorType *VT = DeclType->getAs<VectorType>(); + unsigned maxElements = VT->getNumElements(); + unsigned numEltsInit = 0; + QualType elementType = VT->getElementType(); + + 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<InitListExpr>(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<Expr>(); + + if (ResultExpr != Init) { + // The type was promoted, update initializer list. + IList->setInit(Index, ResultExpr); + } } - } else { - InitializedEntity ElementEntity = - InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); + if (hadError) + ++StructuredIndex; + else + UpdateStructuredListElement(StructuredList, StructuredIndex, ResultExpr); + ++Index; + return; + } + + 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; + // 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); + 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<VectorType>(); - unsigned numIElts = IVT->getNumElements(); + 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<VectorType>(); + 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 (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; } + + // 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, |