From a647caad2dec67ac25b763f06237cfe3c3968b51 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Tue, 6 May 2008 00:23:44 +0000 Subject: [PATCH] Several fixes to SemaInit.cpp. It's still not enabled (since it fails a few tests). Expect to enable it very soon. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50688 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/Sema.h | 4 +-- lib/Sema/SemaInit.cpp | 79 ++++++++++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 6375fad086..5541808ac9 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -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); diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 1485c6fb62..d1f4b25d1d 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -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(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(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(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(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; } -- 2.40.0