Eliminate infinite looping in a wacky case with designated initializers. Simplifies (somewhat) the actually checking of the initializer expression following the designators
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63257 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 406eb26..ad21e7d 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1853,12 +1853,12 @@
InitListExpr *StructuredInitList,
unsigned &StructuredInitIndex);
void CheckSubElementType(InitListExpr *IList, QualType ElemType,
- Expr *expr, unsigned &Index,
+ unsigned &Index,
InitListExpr *StructuredInitList,
unsigned &StructuredInitIndex);
// FIXME: Does DeclType need to be a reference type?
void CheckScalarType(InitListExpr *IList, QualType &DeclType,
- Expr *expr, unsigned &Index,
+ unsigned &Index,
InitListExpr *StructuredInitList,
unsigned &StructuredInitIndex);
void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index,
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 66b938f..b78fc7b 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -188,7 +188,7 @@
InitListExpr *StructuredList,
unsigned &StructuredIndex) {
if (DeclType->isScalarType()) {
- CheckScalarType(IList, DeclType, 0, Index, StructuredList, StructuredIndex);
+ CheckScalarType(IList, DeclType, Index, StructuredList, StructuredIndex);
} else if (DeclType->isVectorType()) {
CheckVectorType(IList, DeclType, Index, StructuredList, StructuredIndex);
} else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
@@ -221,10 +221,10 @@
void InitListChecker::CheckSubElementType(InitListExpr *IList,
QualType ElemType,
- Expr *expr,
unsigned &Index,
InitListExpr *StructuredList,
unsigned &StructuredIndex) {
+ Expr *expr = IList->getInit(Index);
if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
unsigned newIndex = 0;
unsigned newStructuredIndex = 0;
@@ -242,8 +242,7 @@
UpdateStructuredListElement(StructuredList, StructuredIndex, lit);
++Index;
} else if (ElemType->isScalarType()) {
- CheckScalarType(IList, ElemType, expr, Index, StructuredList,
- StructuredIndex);
+ CheckScalarType(IList, ElemType, Index, StructuredList, StructuredIndex);
} else if (expr->getType()->getAsRecordType() &&
SemaRef->Context.typesAreCompatible(
expr->getType().getUnqualifiedType(),
@@ -259,12 +258,11 @@
}
void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
- Expr *expr, unsigned &Index,
+ unsigned &Index,
InitListExpr *StructuredList,
unsigned &StructuredIndex) {
if (Index < IList->getNumInits()) {
- if (!expr)
- expr = IList->getInit(Index);
+ Expr *expr = IList->getInit(Index);
if (isa<InitListExpr>(expr)) {
SemaRef->Diag(IList->getLocStart(),
diag::err_many_braces_around_scalar_init)
@@ -288,12 +286,7 @@
hadError = true; // types weren't compatible.
else if (savExpr != expr) {
// The type was promoted, update initializer list.
- if (DesignatedInitExpr *DIE
- = dyn_cast<DesignatedInitExpr>(IList->getInit(Index)))
- DIE->setInit(expr);
- else
- IList->setInit(Index, expr);
-
+ IList->setInit(Index, expr);
}
if (hadError)
++StructuredIndex;
@@ -323,7 +316,7 @@
// Don't attempt to go past the end of the init list
if (Index >= IList->getNumInits())
break;
- CheckSubElementType(IList, elementType, IList->getInit(Index), Index,
+ CheckSubElementType(IList, elementType, Index,
StructuredList, StructuredIndex);
}
}
@@ -417,7 +410,7 @@
break;
// Check this element.
- CheckSubElementType(IList, elementType, IList->getInit(Index), Index,
+ CheckSubElementType(IList, elementType, Index,
StructuredList, StructuredIndex);
++elementIndex;
@@ -498,7 +491,7 @@
continue;
}
- CheckSubElementType(IList, Field->getType(), IList->getInit(Index), Index,
+ CheckSubElementType(IList, Field->getType(), Index,
StructuredList, StructuredIndex);
if (DeclType->isUnionType())
break;
@@ -559,8 +552,22 @@
if (D == DIE->designators_end()) {
// Check the actual initialization for the designated object type.
bool prevHadError = hadError;
- CheckSubElementType(IList, CurrentObjectType, DIE->getInit(), Index,
+
+ // Temporarily remove the designator expression from the
+ // initializer list that the child calls see, so that we don't try
+ // to re-process the designator.
+ unsigned OldIndex = Index;
+ IList->setInit(OldIndex, DIE->getInit());
+
+ CheckSubElementType(IList, CurrentObjectType, Index,
StructuredList, StructuredIndex);
+
+ // Restore the designated initializer expression in the syntactic
+ // form of the initializer list.
+ if (IList->getInit(OldIndex) != DIE->getInit())
+ DIE->setInit(IList->getInit(OldIndex));
+ IList->setInit(OldIndex, DIE);
+
return hadError && !prevHadError;
}
diff --git a/test/Sema/designated-initializers.c b/test/Sema/designated-initializers.c
index db099dd..5c61faa 100644
--- a/test/Sema/designated-initializers.c
+++ b/test/Sema/designated-initializers.c
@@ -137,5 +137,13 @@
};
}
-// FIXME: we need to
+// FIXME: How do we test that this initializes the long properly?
union { char c; long l; } u1 = { .l = 0xFFFF };
+
+extern float global_float;
+
+struct XX { int a, *b; };
+struct XY { int before; struct XX xx, *xp; float* after; } xy[] = {
+ 0, 0, &xy[0].xx.a, &xy[0].xx, &global_float,
+ [1].xx = 0, &xy[1].xx.a, &xy[1].xx, &global_float
+};