diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Expr.cpp | 13 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/CGExprComplex.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 28 |
8 files changed, 53 insertions, 22 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index c1c8084cd5..8a04198293 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -735,6 +735,8 @@ bool Expr::isConstantInitializer(ASTContext &Ctx) const { } return true; } + case ImplicitValueInitExprClass: + return true; case ParenExprClass: { return cast<ParenExpr>(this)->getSubExpr()->isConstantInitializer(Ctx); } @@ -1672,7 +1674,7 @@ Stmt::child_iterator InitListExpr::child_end() { return InitExprs.size() ? &InitExprs[0] + InitExprs.size() : 0; } -/// DesignatedInitExpr +// DesignatedInitExpr Stmt::child_iterator DesignatedInitExpr::child_begin() { char* Ptr = static_cast<char*>(static_cast<void *>(this)); Ptr += sizeof(DesignatedInitExpr); @@ -1683,6 +1685,15 @@ Stmt::child_iterator DesignatedInitExpr::child_end() { return child_iterator(&*child_begin() + NumSubExprs); } +// ImplicitValueInitExpr +Stmt::child_iterator ImplicitValueInitExpr::child_begin() { + return child_iterator(); +} + +Stmt::child_iterator ImplicitValueInitExpr::child_end() { + return child_iterator(); +} + // ObjCStringLiteral Stmt::child_iterator ObjCStringLiteral::child_begin() { return child_iterator(); diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 7a558ab8dd..27bab206a4 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -906,6 +906,10 @@ void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { PrintExpr(Node->getInit()); } +void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { + OS << "/*implicit*/" << Node->getType().getAsString() << "()"; +} + void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { OS << "va_arg("; PrintExpr(Node->getSubExpr()); diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index b487bacc71..f985763b5c 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -339,10 +339,10 @@ void AggExprEmitter::EmitNonConstInit(InitListExpr *E) { void AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) { // FIXME: Are initializers affected by volatile? - if (E->getType()->isComplexType()) { - CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false); - } else if (isa<CXXZeroInitValueExpr>(E)) { + if (isa<ImplicitValueInitExpr>(E)) { EmitNullInitializationToLValue(LV, E->getType()); + } else if (E->getType()->isComplexType()) { + CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false); } else if (CGF.hasAggregateLLVMType(E->getType())) { CGF.EmitAnyExpr(E, LV.getAddress(), false); } else { diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index 73fceedee5..387635cb06 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -130,6 +130,12 @@ public: llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); return ComplexPairTy(Null, Null); } + ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { + assert(E->getType()->isAnyComplexType() && "Expected complex type!"); + QualType Elem = E->getType()->getAsComplexType()->getElementType(); + llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); + return ComplexPairTy(Null, Null); + } struct BinOpInfo { ComplexPairTy LHS; diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index e523ab3acf..3aedf9bc7f 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -248,11 +248,6 @@ public: FieldDecl* curField = ILE->getInitializedFieldInUnion(); if (!curField) { -#ifndef NDEBUG -#endif - } - - if (!curField) { // There's no field to initialize, so value-initialize the union. #ifndef NDEBUG // Make sure that it's really an empty and not a failure of diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index dd8b30041e..f855e23ba0 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -200,6 +200,9 @@ public: return V; } + Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) { + return llvm::Constant::getNullValue(ConvertType(E->getType())); + } Value *VisitImplicitCastExpr(const ImplicitCastExpr *E); Value *VisitCastExpr(const CastExpr *E) { return EmitCastExpr(E->getSubExpr(), E->getType()); 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 |