Several fixes to SemaInit.cpp. It's still not enabled (since it fails a few tests). Expect to enable it very soon.

llvm-svn: 50688
This commit is contained in:
Steve Naroff
2008-05-06 00:23:44 +00:00
parent 72a0bc148c
commit 125d73dc84
2 changed files with 51 additions and 34 deletions

View File

@@ -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);

View File

@@ -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<InitListExpr>(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<InitListExpr>(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<InitListExpr>(expr)) {
unsigned newIndex = 0;
CheckExplicitInitList(SubInitList, fieldType, newIndex);
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
CheckImplicitInitList(IList, fieldType, Index);
} else if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
unsigned newIndex = 0;
CheckExplicitInitList(SubInitList, elementType, newIndex);
Index++;
} else {
CheckImplicitInitList(IList, elementType, Index);
Index++;
}
if (DeclType->isUnionType())
break;
}