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
This commit is contained in:
John McCall 2010-10-30 00:11:39 +00:00
Родитель 978e3a274a
Коммит 20e047abc5
2 изменённых файлов: 90 добавлений и 52 удалений

Просмотреть файл

@ -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 (Index >= IList->getNumInits())
return;
if (!SemaRef.getLangOptions().OpenCL) {
InitializedEntity ElementEntity =
InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
const VectorType *VT = DeclType->getAs<VectorType>();
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<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>();
// 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<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 (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<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;
}
}
// 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,

Просмотреть файл

@ -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'}}
}