]> granicus.if.org Git - clang/commitdiff
Several fixes to SemaInit.cpp. It's still not enabled (since it fails a few tests...
authorSteve Naroff <snaroff@apple.com>
Tue, 6 May 2008 00:23:44 +0000 (00:23 +0000)
committerSteve Naroff <snaroff@apple.com>
Tue, 6 May 2008 00:23:44 +0000 (00:23 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50688 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaInit.cpp

index 6375fad0869a4b3d403f829a7be8df73a7a3c9bf..5541808ac928377ab24a9704424f1d99c1855bfb 100644 (file)
@@ -902,7 +902,7 @@ class InitListChecker {
   
   void CheckImplicitInitList(InitListExpr *ParentIList, QualType T, 
                              unsigned &Index);
-  void CheckExplicitInitList(InitListExpr *IList, QualType T,
+  void CheckExplicitInitList(InitListExpr *IList, QualType &T,
                              unsigned &Index);
 
   void CheckElementTypes(InitListExpr *IList, QualType &DeclType, 
@@ -912,7 +912,7 @@ class InitListChecker {
                        unsigned &Index);
   void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index);
   void CheckStructUnionTypes(InitListExpr *IList, QualType DeclType, 
-                             unsigned &Index);
+                             unsigned &Index, bool topLevel = false);
   void CheckArrayType(InitListExpr *IList, QualType &DeclType, unsigned &Index);
   
   int numArrayElements(QualType DeclType);
index 1485c6fb62691640b8dddf194fcb12cc55337733..d1f4b25d1deaf49e941500c484984e55087cf23a 100644 (file)
@@ -24,7 +24,25 @@ InitListChecker::InitListChecker(Sema *S, InitListExpr *IL, QualType &T) {
   
   if (IL) {
     unsigned newIndex = 0;
-    CheckExplicitInitList(IL, T, newIndex);
+    
+    // Special case the following, which should produce an error.
+    //
+    // struct foo { int z; } w;
+    // int bar (void) {
+    //   struct foo bad = { w };
+    //   return bad.z;
+    // }
+    if (T->isStructureType() || T->isUnionType())
+      CheckStructUnionTypes(IL, T, newIndex, true);
+    else
+      CheckExplicitInitList(IL, T, newIndex);
+      
+    if (!hadError && (newIndex < IL->getNumInits())) {
+      // We have leftover initializers; warn
+      SemaRef->Diag(IL->getInit(newIndex)->getLocStart(), 
+                    diag::warn_excess_initializers, 
+                    IL->getInit(newIndex)->getSourceRange());
+    }
   } else {
     // FIXME: Create an implicit InitListExpr with expressions from the
     // parent checker.
@@ -88,28 +106,18 @@ void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
   
   // Modify the parent InitListExpr to point to the implicit InitListExpr.
   ParentIList->addInit(Index, ILE);
-  
   // Now we can check the types.
-  CheckElementTypes(ParentIList, T, Index);
+  // CheckElementTypes(ParentIList, T, Index);
 }
 
-void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType T,
+void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
                                             unsigned &Index) {
   //assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
-  if (IList->isExplicit()) {
-    IList->setType(T);
-    
-    if (T->isScalarType())
+  if (IList->isExplicit() && T->isScalarType())
       SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init, 
                     IList->getSourceRange());
-  }
   CheckElementTypes(IList, T, Index);
-  if (Index < IList->getNumInits()) {
-    // We have leftover initializers; warn
-    SemaRef->Diag(IList->getInit(Index)->getLocStart(), 
-                  diag::warn_excess_initializers, 
-                  IList->getInit(Index)->getSourceRange());
-  }
+  IList->setType(T);
 }
 
 void InitListChecker::CheckElementTypes(InitListExpr *IList, QualType &DeclType, 
@@ -199,21 +207,22 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
     if (Index >= IList->getNumInits())
       break;
     Expr* expr = IList->getInit(Index);
-    
     // Now, check the expression against the element type.
     if (elementType->isScalarType())
       CheckScalarType(IList, elementType, Index);
-    else if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
+    else if (elementType->isStructureType() || elementType->isUnionType())
+      CheckStructUnionTypes(IList, elementType, Index);
+    else if (StringLiteral *lit =
+             SemaRef->IsStringLiteralInit(expr, elementType)) {
+      SemaRef->CheckStringLiteralInit(lit, elementType);
+      Index++;
+    } else if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
       unsigned newIndex = 0;
       CheckExplicitInitList(SubInitList, elementType, newIndex);
       Index++;
-#if 0
-    } else if (DeclType->isIncompleteArrayType()) {
-      // FIXME: Figure out how to call CheckImplicit InitList.
-      CheckElementTypes(IList, elementType, Index);
-#endif
     } else {
       CheckImplicitInitList(IList, elementType, Index);
+      Index++;
     }
   }
   if (DeclType->isIncompleteArrayType()) {
@@ -236,8 +245,9 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
 
 void InitListChecker::CheckStructUnionTypes(InitListExpr *IList, 
                                             QualType DeclType, 
-                                            unsigned &Index) {
-  if (Index < IList->getNumInits() && !IList->isExplicit() &&
+                                            unsigned &Index,
+                                            bool topLevel) {
+  if (Index < IList->getNumInits() && !topLevel &&
       SemaRef->Context.typesAreCompatible(
         IList->getInit(Index)->getType(), DeclType)) {
     // We found a compatible struct; per the standard, this initializes the
@@ -270,16 +280,23 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
         // Don't initialize unnamed fields, e.g. "int : 20;"
         continue;
       }
-      QualType fieldType = curField->getType();
+      QualType elementType = curField->getType();
       Expr* expr = IList->getInit(Index);
-      if (fieldType->isScalarType())
-        CheckScalarType(IList, fieldType, Index);
-      else if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
+      if (elementType->isScalarType())
+        CheckScalarType(IList, elementType, Index);
+      else if (elementType->isStructureType() || elementType->isUnionType())
+        CheckStructUnionTypes(IList, elementType, Index);
+      else if (StringLiteral *lit =SemaRef->IsStringLiteralInit(expr, elementType)) {
+        SemaRef->CheckStringLiteralInit(lit, elementType);
+        Index++;
+      } else if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
         unsigned newIndex = 0;
-        CheckExplicitInitList(SubInitList, fieldType, newIndex);
+        CheckExplicitInitList(SubInitList, elementType, newIndex);
         Index++;
-      } else
-        CheckImplicitInitList(IList, fieldType, Index);
+      } else {
+        CheckImplicitInitList(IList, elementType, Index);
+        Index++;
+      }
       if (DeclType->isUnionType())
         break;
     }