[cfe-commits] r159904 - in /cfe/trunk: lib/AST/ExprConstant.cpp test/CodeGenCXX/const-init-cxx11.cpp test/SemaCXX/constant-expression-cxx11.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Sat Jul 7 15:48:24 PDT 2012
Author: rsmith
Date: Sat Jul 7 17:48:24 2012
New Revision: 159904
URL: http://llvm.org/viewvc/llvm-project?rev=159904&view=rev
Log:
PR13290: Constant-evaluation support for CXXConstructExprs which construct a
multidimensional array of class type. Also, preserve zero-initialization when
evaluating an initializer list for an array, in case the initializers refer to
later elements (which have preceding zero-initialization).
Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/CodeGenCXX/const-init-cxx11.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=159904&r1=159903&r2=159904&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sat Jul 7 17:48:24 2012
@@ -3867,8 +3867,24 @@
bool Success = true;
+ assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
+ "zero-initialized array shouldn't have any initialized elts");
+ APValue Filler;
+ if (Result.isArray() && Result.hasArrayFiller())
+ Filler = Result.getArrayFiller();
+
Result = APValue(APValue::UninitArray(), E->getNumInits(),
CAT->getSize().getZExtValue());
+
+ // If the array was previously zero-initialized, preserve the
+ // zero-initialized values.
+ if (!Filler.isUninit()) {
+ for (unsigned I = 0, E = Result.getArrayInitializedElts(); I != E; ++I)
+ Result.getArrayInitializedElt(I) = Filler;
+ if (Result.hasArrayFiller())
+ Result.getArrayFiller() = Filler;
+ }
+
LValue Subobject = This;
Subobject.addArray(Info, E, CAT);
unsigned Index = 0;
@@ -3899,11 +3915,24 @@
if (!CAT)
return Error(E);
- bool HadZeroInit = !Result.isUninit();
- if (!HadZeroInit)
- Result = APValue(APValue::UninitArray(), 0, CAT->getSize().getZExtValue());
- if (!Result.hasArrayFiller())
- return true;
+ // FIXME: The Subobject here isn't necessarily right. This rarely matters,
+ // but sometimes does:
+ // struct S { constexpr S() : p(&p) {} void *p; };
+ // S s[10];
+ LValue Subobject = This;
+
+ APValue *Value = &Result;
+ bool HadZeroInit = true;
+ while (CAT) {
+ Subobject.addArray(Info, E, CAT);
+ HadZeroInit &= !Value->isUninit();
+ if (!HadZeroInit)
+ *Value = APValue(APValue::UninitArray(), 0, CAT->getSize().getZExtValue());
+ if (!Value->hasArrayFiller())
+ return true;
+ CAT = Info.Ctx.getAsConstantArrayType(CAT->getElementType());
+ Value = &Value->getArrayFiller();
+ }
const CXXConstructorDecl *FD = E->getConstructor();
@@ -3913,17 +3942,15 @@
return true;
if (ZeroInit) {
- LValue Subobject = This;
- Subobject.addArray(Info, E, CAT);
ImplicitValueInitExpr VIE(CAT->getElementType());
- return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
+ return EvaluateInPlace(*Value, Info, Subobject, &VIE);
}
const CXXRecordDecl *RD = FD->getParent();
if (RD->isUnion())
- Result.getArrayFiller() = APValue((FieldDecl*)0);
+ *Value = APValue((FieldDecl*)0);
else
- Result.getArrayFiller() =
+ *Value =
APValue(APValue::UninitStruct(), RD->getNumBases(),
std::distance(RD->field_begin(), RD->field_end()));
return true;
@@ -3935,23 +3962,16 @@
if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition))
return false;
- // FIXME: The Subobject here isn't necessarily right. This rarely matters,
- // but sometimes does:
- // struct S { constexpr S() : p(&p) {} void *p; };
- // S s[10];
- LValue Subobject = This;
- Subobject.addArray(Info, E, CAT);
-
if (ZeroInit && !HadZeroInit) {
ImplicitValueInitExpr VIE(CAT->getElementType());
- if (!EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE))
+ if (!EvaluateInPlace(*Value, Info, Subobject, &VIE))
return false;
}
llvm::ArrayRef<const Expr*> Args(E->getArgs(), E->getNumArgs());
return HandleConstructorCall(E->getExprLoc(), Subobject, Args,
cast<CXXConstructorDecl>(Definition),
- Info, Result.getArrayFiller());
+ Info, *Value);
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/test/CodeGenCXX/const-init-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/const-init-cxx11.cpp?rev=159904&r1=159903&r2=159904&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/const-init-cxx11.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/const-init-cxx11.cpp Sat Jul 7 17:48:24 2012
@@ -121,6 +121,13 @@
};
// CHECK: @_ZN5Array1eE = constant {{.*}} { [4 x i8] c"foo\00", [4 x i8] c"x\00\00\00" }
extern constexpr E e = E();
+
+ // PR13290
+ struct F { constexpr F() : n(4) {} int n; };
+ // CHECK: @_ZN5Array2f1E = global {{.*}} zeroinitializer
+ F f1[1][1][0] = { };
+ // CHECK: @_ZN5Array2f2E = global {{.* i32 4 .* i32 4 .* i32 4 .* i32 4 .* i32 4 .* i32 4 .* i32 4 .* i32 4}}
+ F f2[2][2][2] = { };
}
namespace MemberPtr {
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=159904&r1=159903&r2=159904&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Sat Jul 7 17:48:24 2012
@@ -494,6 +494,19 @@
};
static_assert(ArrayRVal().elems[3].f() == 0, "");
+constexpr int selfref[2][2][2] = {
+ selfref[1][1][1] + 1, selfref[0][0][0] + 1,
+ selfref[1][0][1] + 1, selfref[0][1][0] + 1,
+ selfref[1][0][0] + 1, selfref[0][1][1] + 1 };
+static_assert(selfref[0][0][0] == 1, "");
+static_assert(selfref[0][0][1] == 2, "");
+static_assert(selfref[0][1][0] == 1, "");
+static_assert(selfref[0][1][1] == 2, "");
+static_assert(selfref[1][0][0] == 1, "");
+static_assert(selfref[1][0][1] == 3, "");
+static_assert(selfref[1][1][0] == 0, "");
+static_assert(selfref[1][1][1] == 0, "");
+
}
namespace DependentValues {
More information about the cfe-commits
mailing list