Keep track of whether a C++ class is an aggregate. Don't allow initialization of non-aggregates with initializer lists.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58757 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 5dc571c..c8c253a 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -701,6 +701,23 @@
                   Init->getSourceRange());
 
     return CheckSingleInitializer(Init, DeclType);
+  } else if (getLangOptions().CPlusPlus) {
+    // C++ [dcl.init]p14:
+    //   [...] If the class is an aggregate (8.5.1), and the initializer
+    //   is a brace-enclosed list, see 8.5.1.
+    //
+    // Note: 8.5.1 is handled below; here, we diagnose the case where
+    // we have an initializer list and a destination type that is not
+    // an aggregate.
+    // FIXME: In C++0x, this is yet another form of initialization.
+    if (const RecordType *ClassRec = DeclType->getAsRecordType()) {
+      const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassRec->getDecl());
+      if (!ClassDecl->isAggregate())
+        return Diag(InitLoc,
+                    diag::err_init_non_aggr_init_list,
+                    DeclType.getAsString(),
+                    Init->getSourceRange());
+    }
   }
 
   InitListChecker CheckInitList(this, InitList, DeclType);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index b95ebf0..53051ff 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -461,6 +461,15 @@
   // member decls.
   CXXClassMemberWrapper(Member).setAccess(AS);
 
+  // C++ [dcl.init.aggr]p1:
+  //   An aggregate is an array or a class (clause 9) with [...] no
+  //   private or protected non-static data members (clause 11).
+  if (isInstField && (AS == AS_private || AS == AS_protected))
+    cast<CXXRecordDecl>(CurContext)->setAggregate(false);
+
+  // FIXME: If the member is a virtual function, mark it its class as
+  // a non-aggregate.
+
   if (BitWidth) {
     // C++ 9.6p2: Only when declaring an unnamed bit-field may the
     // constant-expression be a value equal to zero.