[cfe-commits] r148035 - in /cfe/trunk: lib/AST/ExprConstant.cpp test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp test/SemaCXX/constant-expression-cxx11.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Thu Jan 12 10:54:33 PST 2012
Author: rsmith
Date: Thu Jan 12 12:54:33 2012
New Revision: 148035
URL: http://llvm.org/viewvc/llvm-project?rev=148035&view=rev
Log:
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).
Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp
cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=148035&r1=148034&r2=148035&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Jan 12 12:54:33 2012
@@ -3015,14 +3015,20 @@
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 @@
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 @@
// 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 @@
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 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 @@
LValue Subobject = This;
Subobject.addArray(Info, E, CAT);
- if (ZeroInit) {
+ if (ZeroInit && !HadZeroInit) {
ImplicitValueInitExpr VIE(CAT->getElementType());
if (!EvaluateConstantExpression(Result.getArrayFiller(), Info, Subobject,
&VIE))
Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp?rev=148035&r1=148034&r2=148035&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp Thu Jan 12 12:54:33 2012
@@ -5,3 +5,15 @@
char x2[] = "hello";
extern char x2[6];
+
+char x3[] = { "hello" };
+extern char x3[6];
+
+wchar_t x4[](L"hello");
+extern wchar_t x4[6];
+
+wchar_t x5[] = L"hello";
+extern wchar_t x5[6];
+
+wchar_t x6[] = { L"hello" };
+extern wchar_t x6[6];
Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=148035&r1=148034&r2=148035&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Thu Jan 12 12:54:33 2012
@@ -357,6 +357,8 @@
}
static_assert(MangleChars("constexpr!") == 1768383, "");
+static_assert(MangleChars(u8"constexpr!") == 1768383, "");
+static_assert(MangleChars(L"constexpr!") == 1768383, "");
static_assert(MangleChars(u"constexpr!") == 1768383, "");
static_assert(MangleChars(U"constexpr!") == 1768383, "");
@@ -404,6 +406,12 @@
static_assert(t.c[5] == 0, "");
static_assert(t.c[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
+struct U {
+ wchar_t chars[6];
+ int n;
+} constexpr u = { { L"test" }, 0 };
+static_assert(u.chars[2] == L's', "");
+
}
namespace Array {
@@ -726,6 +734,12 @@
static_assert(*(&(u[1].b) + 1 + 1) == 3, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element 2 of non-array object}}
static_assert((&(u[1]) + 1 + 1)->b == 3, "");
+constexpr U v = {};
+static_assert(v.a == 0, "");
+
+union Empty {};
+constexpr Empty e = {};
+
// Make sure we handle trivial copy constructors for unions.
constexpr U x = {42};
constexpr U y = x;
More information about the cfe-commits
mailing list