[cfe-commits] r117749 - in /cfe/trunk: lib/Sema/SemaInit.cpp test/Sema/vector-init.c

John McCall rjmccall at apple.com
Fri Oct 29 17:11:39 PDT 2010


Author: rjmccall
Date: Fri Oct 29 19:11:39 2010
New Revision: 117749

URL: http://llvm.org/viewvc/llvm-project?rev=117749&view=rev
Log:
When list-initializing a vector, try to copy-initialize from vectors instead
of descending into the subelements.

rdar://problem/8345836


Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/Sema/vector-init.c

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=117749&r1=117748&r2=117749&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Oct 29 19:11:39 2010
@@ -839,66 +839,95 @@
                                       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,

Modified: cfe/trunk/test/Sema/vector-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vector-init.c?rev=117749&r1=117748&r2=117749&view=diff
==============================================================================
--- cfe/trunk/test/Sema/vector-init.c (original)
+++ cfe/trunk/test/Sema/vector-init.c Fri Oct 29 19:11:39 2010
@@ -33,3 +33,12 @@
 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'}}
+}





More information about the cfe-commits mailing list