summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-08-29 22:49:33 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-08-29 22:49:33 +0000
commitdbc57bfc8e56a71dd932ca04b7c211e5bf44e80e (patch)
tree3f469a8d26ea460b4a2cb02c240738c620a59cf2
parent5de0d302f1834e1ef200a3c567f83bcf2439fa60 (diff)
downloadclang-dbc57bfc8e56a71dd932ca04b7c211e5bf44e80e.tar.gz
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
-rw-r--r--lib/Sema/SemaInit.cpp57
-rw-r--r--test/Sema/designated-initializers.c6
2 files changed, 15 insertions, 48 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 7c33e99803..21e7f120f4 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -274,11 +274,10 @@ namespace {
/// initialize the subobjects after the one designated.
class InitListChecker {
Sema &SemaRef;
- bool hadError;
+ bool hadError = false;
bool VerifyOnly; // no diagnostics, no structure building
bool TreatUnavailableAsInvalid; // Used only in VerifyOnly mode.
- llvm::DenseMap<InitListExpr *, InitListExpr *> SyntacticToSemantic;
- InitListExpr *FullyStructuredList;
+ InitListExpr *FullyStructuredList = nullptr;
void CheckImplicitInitList(const InitializedEntity &Entity,
InitListExpr *ParentIList, QualType T,
@@ -842,18 +841,18 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
}
InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity,
- InitListExpr *IL, QualType &T,
- bool VerifyOnly,
+ InitListExpr *IL, QualType &T, bool VerifyOnly,
bool TreatUnavailableAsInvalid)
: SemaRef(S), VerifyOnly(VerifyOnly),
TreatUnavailableAsInvalid(TreatUnavailableAsInvalid) {
// FIXME: Check that IL isn't already the semantic form of some other
// 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,
/*TopLevelObject=*/true);
@@ -1075,11 +1074,6 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity,
InitListExpr *IList, QualType &T,
InitListExpr *StructuredList,
bool TopLevelObject) {
- if (!VerifyOnly) {
- SyntacticToSemantic[IList] = StructuredList;
- StructuredList->setSyntacticForm(IList);
- }
-
unsigned Index = 0, StructuredIndex = 0;
CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true,
Index, StructuredList, StructuredIndex, TopLevelObject);
@@ -1231,29 +1225,8 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
IsStringInit(SubInitList->getInit(0), ElemType, SemaRef.Context) ==
SIF_None) {
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)) {
// This happens during template instantiation when we see an InitListExpr
// that we've already checked once.
@@ -1265,7 +1238,7 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
return;
}
- if (SemaRef.getLangOpts().CPlusPlus) {
+ if (SemaRef.getLangOpts().CPlusPlus || isa<InitListExpr>(expr)) {
// C++ [dcl.init.aggr]p2:
// Each member is copy-initialized from the corresponding
// initializer-clause.
@@ -2316,7 +2289,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
// Determine the structural initializer list that corresponds to the
// current subobject.
if (IsFirstDesignator)
- StructuredList = SyntacticToSemantic.lookup(IList);
+ StructuredList = FullyStructuredList;
else {
Expr *ExistingInit = StructuredIndex < StructuredList->getNumInits() ?
StructuredList->getInit(StructuredIndex) : nullptr;
@@ -2833,9 +2806,7 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
if (VerifyOnly)
return nullptr; // No structured list in verification-only mode.
Expr *ExistingInit = nullptr;
- if (!StructuredList)
- ExistingInit = SyntacticToSemantic.lookup(IList);
- else if (StructuredIndex < StructuredList->getNumInits())
+ if (StructuredList && StructuredIndex < StructuredList->getNumInits())
ExistingInit = StructuredList->getInit(StructuredIndex);
if (InitListExpr *Result = dyn_cast_or_null<InitListExpr>(ExistingInit))
@@ -2918,10 +2889,6 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
// lists.
if (StructuredList)
StructuredList->updateInit(SemaRef.Context, StructuredIndex, Result);
- else {
- Result->setSyntacticForm(IList);
- SyntacticToSemantic[IList] = Result;
- }
return Result;
}
diff --git a/test/Sema/designated-initializers.c b/test/Sema/designated-initializers.c
index 43f3318824..0a72e8ff37 100644
--- a/test/Sema/designated-initializers.c
+++ b/test/Sema/designated-initializers.c
@@ -46,7 +46,7 @@ struct point array[10] = {
struct point array2[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 ... 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] = {
@@ -364,7 +364,7 @@ struct {
},
.u1 = {
- .a = 0,
- .b = 0,
+ .a = 0, // expected-note {{previous initialization is here}}
+ .b = 0, // expected-warning {{initializer overrides prior initialization of this subobject}}
},
};