From f6d2752f1272a679378ddd6416810144b3225ad7 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 29 Jan 2009 00:39:20 +0000 Subject: [PATCH] Eliminate infinite looping in a wacky case with designated initializers. Simplifies (somewhat) the actually checking of the initializer expression following the designators llvm-svn: 63257 --- clang/lib/Sema/Sema.h | 4 +-- clang/lib/Sema/SemaInit.cpp | 41 +++++++++++++---------- clang/test/Sema/designated-initializers.c | 10 +++++- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 406eb2645075..ad21e7d271c6 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1853,12 +1853,12 @@ class InitListChecker { 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/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 66b938ff0713..b78fc7b1e629 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -188,7 +188,7 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList, 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::CheckListElementTypes(InitListExpr *IList, 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(expr)) { unsigned newIndex = 0; unsigned newStructuredIndex = 0; @@ -242,8 +242,7 @@ void InitListChecker::CheckSubElementType(InitListExpr *IList, 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::CheckSubElementType(InitListExpr *IList, } 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(expr)) { SemaRef->Diag(IList->getLocStart(), diag::err_many_braces_around_scalar_init) @@ -288,12 +286,7 @@ void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType, hadError = true; // types weren't compatible. else if (savExpr != expr) { // The type was promoted, update initializer list. - if (DesignatedInitExpr *DIE - = dyn_cast(IList->getInit(Index))) - DIE->setInit(expr); - else - IList->setInit(Index, expr); - + IList->setInit(Index, expr); } if (hadError) ++StructuredIndex; @@ -323,7 +316,7 @@ void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType, // 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 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, break; // Check this element. - CheckSubElementType(IList, elementType, IList->getInit(Index), Index, + CheckSubElementType(IList, elementType, Index, StructuredList, StructuredIndex); ++elementIndex; @@ -498,7 +491,7 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList, continue; } - CheckSubElementType(IList, Field->getType(), IList->getInit(Index), Index, + CheckSubElementType(IList, Field->getType(), Index, StructuredList, StructuredIndex); if (DeclType->isUnionType()) break; @@ -559,8 +552,22 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList, 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/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c index db099dd178ba..5c61faa66794 100644 --- a/clang/test/Sema/designated-initializers.c +++ b/clang/test/Sema/designated-initializers.c @@ -137,5 +137,13 @@ void test() { }; } -// 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 +};