aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Expr.cpp13
-rw-r--r--lib/AST/StmtPrinter.cpp4
-rw-r--r--lib/CodeGen/CGExprAgg.cpp6
-rw-r--r--lib/CodeGen/CGExprComplex.cpp6
-rw-r--r--lib/CodeGen/CGExprConstant.cpp5
-rw-r--r--lib/CodeGen/CGExprScalar.cpp3
-rw-r--r--lib/Sema/SemaDecl.cpp10
-rw-r--r--lib/Sema/SemaInit.cpp28
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