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.
llvm-svn: 169662
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 210dcb6..d3a0c1a 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/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.