Преглед на файлове

Refactor InitListChecker to check only a single (explicit) initializer
list, rather than recursively checking multiple lists in C.

This simplification is in preparation for making InitListChecker
maintain more state that's specific to the explicit initializer list,
particularly when handling designated initialization.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@370418 91177308-0d34-0410-b5e6-96231b3b80d8

Richard Smith преди 6 години
родител
ревизия
dbc57bfc8e
променени са 2 файла, в които са добавени 15 реда и са изтрити 48 реда
  1. 12 45
      lib/Sema/SemaInit.cpp
  2. 3 3
      test/Sema/designated-initializers.c

+ 12 - 45
lib/Sema/SemaInit.cpp

@@ -274,11 +274,10 @@ namespace {
 /// initialize the subobjects after the one designated.
 /// initialize the subobjects after the one designated.
 class InitListChecker {
 class InitListChecker {
   Sema &SemaRef;
   Sema &SemaRef;
-  bool hadError;
+  bool hadError = false;
   bool VerifyOnly; // no diagnostics, no structure building
   bool VerifyOnly; // no diagnostics, no structure building
   bool TreatUnavailableAsInvalid; // Used only in VerifyOnly mode.
   bool TreatUnavailableAsInvalid; // Used only in VerifyOnly mode.
-  llvm::DenseMap<InitListExpr *, InitListExpr *> SyntacticToSemantic;
-  InitListExpr *FullyStructuredList;
+  InitListExpr *FullyStructuredList = nullptr;
 
 
   void CheckImplicitInitList(const InitializedEntity &Entity,
   void CheckImplicitInitList(const InitializedEntity &Entity,
                              InitListExpr *ParentIList, QualType T,
                              InitListExpr *ParentIList, QualType T,
@@ -842,18 +841,18 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
 }
 }
 
 
 InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity,
 InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity,
-                                 InitListExpr *IL, QualType &T,
-                                 bool VerifyOnly,
+                                 InitListExpr *IL, QualType &T, bool VerifyOnly,
                                  bool TreatUnavailableAsInvalid)
                                  bool TreatUnavailableAsInvalid)
   : SemaRef(S), VerifyOnly(VerifyOnly),
   : SemaRef(S), VerifyOnly(VerifyOnly),
     TreatUnavailableAsInvalid(TreatUnavailableAsInvalid) {
     TreatUnavailableAsInvalid(TreatUnavailableAsInvalid) {
   // FIXME: Check that IL isn't already the semantic form of some other
   // FIXME: Check that IL isn't already the semantic form of some other
   // InitListExpr. If it is, we'd create a broken AST.
   // InitListExpr. If it is, we'd create a broken AST.
 
 
-  hadError = false;
-
-  FullyStructuredList =
-      getStructuredSubobjectInit(IL, 0, T, nullptr, 0, IL->getSourceRange());
+  if (!VerifyOnly) {
+    FullyStructuredList =
+        getStructuredSubobjectInit(IL, 0, T, nullptr, 0, IL->getSourceRange());
+    FullyStructuredList->setSyntacticForm(IL);
+  }
   CheckExplicitInitList(Entity, IL, T, FullyStructuredList,
   CheckExplicitInitList(Entity, IL, T, FullyStructuredList,
                         /*TopLevelObject=*/true);
                         /*TopLevelObject=*/true);
 
 
@@ -1075,11 +1074,6 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity,
                                             InitListExpr *IList, QualType &T,
                                             InitListExpr *IList, QualType &T,
                                             InitListExpr *StructuredList,
                                             InitListExpr *StructuredList,
                                             bool TopLevelObject) {
                                             bool TopLevelObject) {
-  if (!VerifyOnly) {
-    SyntacticToSemantic[IList] = StructuredList;
-    StructuredList->setSyntacticForm(IList);
-  }
-
   unsigned Index = 0, StructuredIndex = 0;
   unsigned Index = 0, StructuredIndex = 0;
   CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true,
   CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true,
                         Index, StructuredList, StructuredIndex, TopLevelObject);
                         Index, StructuredList, StructuredIndex, TopLevelObject);
@@ -1231,29 +1225,8 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
         IsStringInit(SubInitList->getInit(0), ElemType, SemaRef.Context) ==
         IsStringInit(SubInitList->getInit(0), ElemType, SemaRef.Context) ==
         SIF_None) {
         SIF_None) {
       expr = SubInitList->getInit(0);
       expr = SubInitList->getInit(0);
-    } else if (!SemaRef.getLangOpts().CPlusPlus) {
-      InitListExpr *InnerStructuredList
-        = getStructuredSubobjectInit(IList, Index, ElemType,
-                                     StructuredList, StructuredIndex,
-                                     SubInitList->getSourceRange(), true);
-      CheckExplicitInitList(Entity, SubInitList, ElemType,
-                            InnerStructuredList);
-
-      if (!hadError && !VerifyOnly) {
-        bool RequiresSecondPass = false;
-        FillInEmptyInitializations(Entity, InnerStructuredList,
-                                   RequiresSecondPass, StructuredList,
-                                   StructuredIndex);
-        if (RequiresSecondPass && !hadError)
-          FillInEmptyInitializations(Entity, InnerStructuredList,
-                                     RequiresSecondPass, StructuredList,
-                                     StructuredIndex);
-      }
-      ++StructuredIndex;
-      ++Index;
-      return;
     }
     }
-    // C++ initialization is handled later.
+    // Nested aggregate initialization and C++ initialization are handled later.
   } else if (isa<ImplicitValueInitExpr>(expr)) {
   } else if (isa<ImplicitValueInitExpr>(expr)) {
     // This happens during template instantiation when we see an InitListExpr
     // This happens during template instantiation when we see an InitListExpr
     // that we've already checked once.
     // that we've already checked once.
@@ -1265,7 +1238,7 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
     return;
     return;
   }
   }
 
 
-  if (SemaRef.getLangOpts().CPlusPlus) {
+  if (SemaRef.getLangOpts().CPlusPlus || isa<InitListExpr>(expr)) {
     // C++ [dcl.init.aggr]p2:
     // C++ [dcl.init.aggr]p2:
     //   Each member is copy-initialized from the corresponding
     //   Each member is copy-initialized from the corresponding
     //   initializer-clause.
     //   initializer-clause.
@@ -2316,7 +2289,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
     // Determine the structural initializer list that corresponds to the
     // Determine the structural initializer list that corresponds to the
     // current subobject.
     // current subobject.
     if (IsFirstDesignator)
     if (IsFirstDesignator)
-      StructuredList = SyntacticToSemantic.lookup(IList);
+      StructuredList = FullyStructuredList;
     else {
     else {
       Expr *ExistingInit = StructuredIndex < StructuredList->getNumInits() ?
       Expr *ExistingInit = StructuredIndex < StructuredList->getNumInits() ?
           StructuredList->getInit(StructuredIndex) : nullptr;
           StructuredList->getInit(StructuredIndex) : nullptr;
@@ -2833,9 +2806,7 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
   if (VerifyOnly)
   if (VerifyOnly)
     return nullptr; // No structured list in verification-only mode.
     return nullptr; // No structured list in verification-only mode.
   Expr *ExistingInit = nullptr;
   Expr *ExistingInit = nullptr;
-  if (!StructuredList)
-    ExistingInit = SyntacticToSemantic.lookup(IList);
-  else if (StructuredIndex < StructuredList->getNumInits())
+  if (StructuredList && StructuredIndex < StructuredList->getNumInits())
     ExistingInit = StructuredList->getInit(StructuredIndex);
     ExistingInit = StructuredList->getInit(StructuredIndex);
 
 
   if (InitListExpr *Result = dyn_cast_or_null<InitListExpr>(ExistingInit))
   if (InitListExpr *Result = dyn_cast_or_null<InitListExpr>(ExistingInit))
@@ -2918,10 +2889,6 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
   // lists.
   // lists.
   if (StructuredList)
   if (StructuredList)
     StructuredList->updateInit(SemaRef.Context, StructuredIndex, Result);
     StructuredList->updateInit(SemaRef.Context, StructuredIndex, Result);
-  else {
-    Result->setSyntacticForm(IList);
-    SyntacticToSemantic[IList] = Result;
-  }
 
 
   return Result;
   return Result;
 }
 }

+ 3 - 3
test/Sema/designated-initializers.c

@@ -46,7 +46,7 @@ struct point array[10] = {
 struct point array2[10] = {
 struct point array2[10] = {
   [10].x = 2.0, // expected-error{{array designator index (10) exceeds array bounds (10)}}
   [10].x = 2.0, // expected-error{{array designator index (10) exceeds array bounds (10)}}
   [4 ... 5].y = 2.0, // expected-note 2 {{previous initialization is here}}
   [4 ... 5].y = 2.0, // expected-note 2 {{previous initialization is here}}
-  [4 ... 6] = { .x = 3, .y = 4.0 }  // expected-warning 2 {{subobject initialization overrides initialization of other fields within its enclosing subobject}}
+  [4 ... 6] = { .x = 3, .y = 4.0 }  // expected-warning 2 {{initializer overrides prior initialization of this subobject}}
 };
 };
 
 
 struct point array3[10] = {
 struct point array3[10] = {
@@ -364,7 +364,7 @@ struct {
   },
   },
 
 
   .u1 = {
   .u1 = {
-    .a = 0,
-    .b = 0,
+    .a = 0, // expected-note {{previous initialization is here}}
+    .b = 0, // expected-warning {{initializer overrides prior initialization of this subobject}}
   },
   },
 };
 };