diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 28 |
2 files changed, 25 insertions, 13 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 7572560be1..1559213fcb 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2220,17 +2220,17 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) { if (CompoundLiteralExpr *e = dyn_cast<CompoundLiteralExpr>(Init)) return CheckForConstantInitializer(e->getInitializer(), DclT); + if (isa<ImplicitValueInitExpr>(Init)) { + // FIXME: In C++, check for non-POD types. + return false; + } + if (InitListExpr *Exp = dyn_cast<InitListExpr>(Init)) { unsigned numInits = Exp->getNumInits(); for (unsigned i = 0; i < numInits; i++) { // FIXME: Need to get the type of the declaration for C++, // because it could be a reference? - // Implicitly-generated value initializations are okay. - if (isa<CXXZeroInitValueExpr>(Exp->getInit(i)) && - cast<CXXZeroInitValueExpr>(Exp->getInit(i))->isImplicit()) - continue; - if (CheckForConstantInitializer(Exp->getInit(i), Exp->getInit(i)->getType())) return true; diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 527f965dc3..5d7f705edb 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -17,7 +17,6 @@ #include "clang/Parse/Designator.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Expr.h" -#include "clang/AST/ExprCXX.h" #include <map> using namespace clang; @@ -137,10 +136,9 @@ static void fillInValueInitializations(ASTContext &Context, InitListExpr *ILE) { // FIXME: Check for fields with reference type in C++? if (!ILE->getInit(Init)) ILE->setInit(Init, - new (Context) CXXZeroInitValueExpr(Field->getType(), - SourceLocation(), - SourceLocation())); - else if (InitListExpr *InnerILE = dyn_cast<InitListExpr>(ILE->getInit(Init))) + new (Context) ImplicitValueInitExpr(Field->getType())); + else if (InitListExpr *InnerILE + = dyn_cast<InitListExpr>(ILE->getInit(Init))) fillInValueInitializations(Context, InnerILE); ++Init; } @@ -160,9 +158,7 @@ static void fillInValueInitializations(ASTContext &Context, InitListExpr *ILE) { for (unsigned Init = 0, NumInits = ILE->getNumInits(); Init != NumInits; ++Init) { if (!ILE->getInit(Init)) - ILE->setInit(Init, new (Context) CXXZeroInitValueExpr(ElementType, - SourceLocation(), - SourceLocation())); + ILE->setInit(Init, new (Context) ImplicitValueInitExpr(ElementType)); else if (InitListExpr *InnerILE =dyn_cast<InitListExpr>(ILE->getInit(Init))) fillInValueInitializations(Context, InnerILE); } @@ -550,6 +546,22 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList, hadError = true; return; } + + if (DeclType->isUnionType() && IList->getNumInits() == 0) { + // Value-initialize the first named member of the union. + RecordDecl *RD = DeclType->getAsRecordType()->getDecl(); + for (RecordDecl::field_iterator FieldEnd = RD->field_end(); + Field != FieldEnd; ++Field) { + if (Field->getDeclName()) { + StructuredList->setInitializedFieldInUnion(*Field); + break; + } + } + return; + } + + + // If structDecl is a forward declaration, this loop won't do // anything except look at designated initializers; That's okay, // because an error should get printed out elsewhere. It might be |