Implement C++03 [dcl.init]p5's checking for value-initialization of references
properly, rather than faking it up by pretending that a reference member makes
the default constructor non-trivial. That leads to rejects-valids when putting
such types inside unions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169662 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 210dcb6..d3a0c1a 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -41,7 +41,7 @@
Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true),
HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false),
HasMutableFields(false), HasOnlyCMembers(true),
- HasInClassInitializer(false),
+ HasInClassInitializer(false), HasUninitializedReferenceMember(false),
HasTrivialSpecialMembers(SMF_All),
HasIrrelevantDestructor(true),
HasConstexprNonCopyMoveConstructor(false),
@@ -295,6 +295,9 @@
// Keep track of the presence of mutable fields.
if (BaseClassDecl->hasMutableFields())
data().HasMutableFields = true;
+
+ if (BaseClassDecl->hasUninitializedReferenceMember())
+ data().HasUninitializedReferenceMember = true;
}
if (VBases.empty())
@@ -727,7 +730,8 @@
data().PlainOldData = false;
if (T->isReferenceType()) {
- data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor;
+ if (!Field->hasInClassInitializer())
+ data().HasUninitializedReferenceMember = true;
// C++0x [class]p7:
// A standard-layout class is a class that:
@@ -866,6 +870,10 @@
// parameter is of type 'const M&', 'const volatile M&' or 'M'.
if (!FieldRec->hasCopyAssignmentWithConstParam())
data().ImplicitCopyAssignmentHasConstParam = false;
+
+ if (FieldRec->hasUninitializedReferenceMember() &&
+ !Field->hasInClassInitializer())
+ data().HasUninitializedReferenceMember = true;
}
} else {
// Base element type of field is a non-class type.