[Sema] Don't perform aggregate initialization for types with explicit constructors

Summary:
The C++17 rules for aggregate initialization changed to disallow types with explicit constructors [dcl.init.aggr]p1. This patch implements that new rule.


Reviewers: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D25654

llvm-svn: 288565
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 6df15b0..f1848e8 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -533,6 +533,17 @@
       } else if (Constructor->isMoveConstructor())
         SMKind |= SMF_MoveConstructor;
     }
+
+    // C++ [dcl.init.aggr]p1:
+    //   An aggregate is an array or a class with no user-declared
+    //   constructors [...].
+    // C++11 [dcl.init.aggr]p1: DR1518
+    //  An aggregate is an array or a class with no user-provided, explicit, or
+    //  inherited constructors
+    if (getASTContext().getLangOpts().CPlusPlus11
+            ? (Constructor->isUserProvided() || Constructor->isExplicit())
+            : !Constructor->isImplicit())
+      data().Aggregate = false;
   }
 
   // Handle constructors, including those inherited from base classes.
@@ -546,20 +557,6 @@
     //   constructor [...]
     if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor())
       data().HasConstexprNonCopyMoveConstructor = true;
-
-    // C++ [dcl.init.aggr]p1:
-    //   An aggregate is an array or a class with no user-declared
-    //   constructors [...].
-    // C++11 [dcl.init.aggr]p1:
-    //   An aggregate is an array or a class with no user-provided
-    //   constructors [...].
-    // C++11 [dcl.init.aggr]p1:
-    //   An aggregate is an array or a class with no user-provided
-    //   constructors (including those inherited from a base class) [...].
-    if (getASTContext().getLangOpts().CPlusPlus11
-            ? Constructor->isUserProvided()
-            : !Constructor->isImplicit())
-      data().Aggregate = false;
   }
 
   // Handle destructors.
@@ -989,8 +986,12 @@
 
   if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
     if (Using->getDeclName().getNameKind() ==
-        DeclarationName::CXXConstructorName)
+        DeclarationName::CXXConstructorName) {
       data().HasInheritedConstructor = true;
+      // C++1z [dcl.init.aggr]p1:
+      //  An aggregate is [...] a class [...] with no inherited constructors
+      data().Aggregate = false;
+    }
 
     if (Using->getDeclName().getCXXOverloadedOperator() == OO_Equal)
       data().HasInheritedAssignment = true;