aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2014-03-19 20:38:17 +0000
committerTom Stellard <thomas.stellard@amd.com>2014-03-19 20:38:17 +0000
commitff1805df9d4ed5b79ff9d1fef01ed1b485f605bb (patch)
treef38192e1a76c5fb198d59f1c9882b5207f652d9f
parent36642863577684ea1d4d6d615e85f2c8c20ded82 (diff)
downloadllvm-ff1805df9d4ed5b79ff9d1fef01ed1b485f605bb.zip
llvm-ff1805df9d4ed5b79ff9d1fef01ed1b485f605bb.tar.gz
llvm-ff1805df9d4ed5b79ff9d1fef01ed1b485f605bb.tar.bz2
Merging r203025:
------------------------------------------------------------------------ r203025 | richard-llvm | 2014-03-05 15:32:50 -0800 (Wed, 05 Mar 2014) | 3 lines PR19010: Make sure we initialize (empty) indirect base class subobjects when evaluating trivial default initialization of a literal class type. llvm-svn: 204263
-rw-r--r--clang/lib/AST/ExprConstant.cpp35
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx11.cpp10
2 files changed, 22 insertions, 23 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 390cfe9..4cac4fa 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -5089,16 +5089,15 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
if (!Result.isUninit())
return true;
- if (ZeroInit)
- return ZeroInitialization(E);
-
- const CXXRecordDecl *RD = FD->getParent();
- if (RD->isUnion())
- Result = APValue((FieldDecl*)0);
- else
- Result = APValue(APValue::UninitStruct(), RD->getNumBases(),
- std::distance(RD->field_begin(), RD->field_end()));
- return true;
+ // We can get here in two different ways:
+ // 1) We're performing value-initialization, and should zero-initialize
+ // the object, or
+ // 2) We're performing default-initialization of an object with a trivial
+ // constexpr default constructor, in which case we should start the
+ // lifetimes of all the base subobjects (there can be no data member
+ // subobjects in this case) per [basic.life]p1.
+ // Either way, ZeroInitialization is appropriate.
+ return ZeroInitialization(E);
}
const FunctionDecl *Definition = 0;
@@ -5578,19 +5577,9 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
if (HadZeroInit)
return true;
- if (ZeroInit) {
- ImplicitValueInitExpr VIE(Type);
- return EvaluateInPlace(*Value, Info, Subobject, &VIE);
- }
-
- const CXXRecordDecl *RD = FD->getParent();
- if (RD->isUnion())
- *Value = APValue((FieldDecl*)0);
- else
- *Value =
- APValue(APValue::UninitStruct(), RD->getNumBases(),
- std::distance(RD->field_begin(), RD->field_end()));
- return true;
+ // See RecordExprEvaluator::VisitCXXConstructExpr for explanation.
+ ImplicitValueInitExpr VIE(Type);
+ return EvaluateInPlace(*Value, Info, Subobject, &VIE);
}
const FunctionDecl *Definition = 0;
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 6724be7..d73ee45 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1863,3 +1863,13 @@ namespace BuiltinStrlen {
constexpr char d[] = { 'f', 'o', 'o' }; // no nul terminator.
constexpr int bad = __builtin_strlen(d); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
}
+
+namespace PR19010 {
+ struct Empty {};
+ struct Empty2 : Empty {};
+ struct Test : Empty2 {
+ constexpr Test() {}
+ Empty2 array[2];
+ };
+ void test() { constexpr Test t; }
+}