aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-01-12 18:54:33 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-01-12 18:54:33 +0000
commitec789163a42a7be654ac34aadb750b508954d53c (patch)
tree6546d1b5f6eb005f81af63726a6ea314f132001b /lib/AST/ExprConstant.cpp
parent37969b7e14d6a4dfd934ef6d3738cc90b832ec1d (diff)
constexpr: initialization of a union from an empty initializer-list should
zero-initialize the first union member. Also fix a bug where initializing an array of types compatible with wchar_t from a wide string literal failed in C, and fortify the C++ tests in this area. This part can't be tested without a code change to enable array evaluation in C (where an existing test fails). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148035 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp31
1 files changed, 23 insertions, 8 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 9df53cd5bf..0cae13850d 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -3015,14 +3015,20 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
if (RD->isUnion()) {
- Result = APValue(E->getInitializedFieldInUnion());
- if (!E->getNumInits())
+ const FieldDecl *Field = E->getInitializedFieldInUnion();
+ Result = APValue(Field);
+ if (!Field)
return true;
+
+ // If the initializer list for a union does not contain any elements, the
+ // first element of the union is value-initialized.
+ ImplicitValueInitExpr VIE(Field->getType());
+ const Expr *InitExpr = E->getNumInits() ? E->getInit(0) : &VIE;
+
LValue Subobject = This;
- HandleLValueMember(Info, E->getInit(0), Subobject,
- E->getInitializedFieldInUnion(), &Layout);
+ HandleLValueMember(Info, InitExpr, Subobject, Field, &Layout);
return EvaluateConstantExpression(Result.getUnionValue(), Info,
- Subobject, E->getInit(0));
+ Subobject, InitExpr);
}
assert((!isa<CXXRecordDecl>(RD) || !cast<CXXRecordDecl>(RD)->getNumBases()) &&
@@ -3065,6 +3071,10 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
const CXXConstructorDecl *FD = E->getConstructor();
bool ZeroInit = E->requiresZeroInitialization();
if (CheckTrivialDefaultConstructor(Info, E->getExprLoc(), FD, ZeroInit)) {
+ // If we've already performed zero-initialization, we're already done.
+ if (!Result.isUninit())
+ return true;
+
if (ZeroInit)
return ZeroInitialization(E);
@@ -3391,7 +3401,7 @@ bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
// C++11 [dcl.init.string]p1: A char array [...] can be initialized by [...]
// an appropriately-typed string literal enclosed in braces.
- if (E->getNumInits() == 1 && CAT->getElementType()->isAnyCharacterType() &&
+ if (E->getNumInits() == 1 && E->getInit(0)->isGLValue() &&
Info.Ctx.hasSameUnqualifiedType(E->getType(), E->getInit(0)->getType())) {
LValue LV;
if (!EvaluateLValue(E->getInit(0), LV, Info))
@@ -3446,7 +3456,9 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
if (!CAT)
return Error(E);
- Result = APValue(APValue::UninitArray(), 0, CAT->getSize().getZExtValue());
+ bool HadZeroInit = !Result.isUninit();
+ if (!HadZeroInit)
+ Result = APValue(APValue::UninitArray(), 0, CAT->getSize().getZExtValue());
if (!Result.hasArrayFiller())
return true;
@@ -3454,6 +3466,9 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
bool ZeroInit = E->requiresZeroInitialization();
if (CheckTrivialDefaultConstructor(Info, E->getExprLoc(), FD, ZeroInit)) {
+ if (HadZeroInit)
+ return true;
+
if (ZeroInit) {
LValue Subobject = This;
Subobject.addArray(Info, E, CAT);
@@ -3485,7 +3500,7 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
LValue Subobject = This;
Subobject.addArray(Info, E, CAT);
- if (ZeroInit) {
+ if (ZeroInit && !HadZeroInit) {
ImplicitValueInitExpr VIE(CAT->getElementType());
if (!EvaluateConstantExpression(Result.getArrayFiller(), Info, Subobject,
&VIE))