Replace r134583's fix for PR10290 with one which also works for non-value-dependent cases.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135543 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 263c1bd..cc55e55 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -4894,6 +4894,11 @@
   void InstantiateMemInitializers(CXXConstructorDecl *New,
                                   const CXXConstructorDecl *Tmpl,
                             const MultiLevelTemplateArgumentList &TemplateArgs);
+  bool InstantiateInitializer(Expr *Init,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                              SourceLocation &LParenLoc,
+                              ASTOwningVector<Expr*> &NewArgs,
+                              SourceLocation &RParenLoc);
 
   NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
                           const MultiLevelTemplateArgumentList &TemplateArgs);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index d793daf..9ad9a2f 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1234,8 +1234,9 @@
 }
 
 /// ActOnCXXInClassMemberInitializer - This is invoked after parsing an
-/// in-class initializer for a non-static C++ class member. Such parsing
-/// is deferred until the class is complete.
+/// in-class initializer for a non-static C++ class member, and after
+/// instantiating an in-class initializer in a class template. Such actions
+/// are deferred until the class is complete.
 void
 Sema::ActOnCXXInClassMemberInitializer(Decl *D, SourceLocation EqualLoc,
                                        Expr *InitExpr) {
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 1988f14..8d52951 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1806,34 +1806,16 @@
     FieldDecl *OldField = FieldsWithMemberInitializers[I].first;
     FieldDecl *NewField = FieldsWithMemberInitializers[I].second;
     Expr *OldInit = OldField->getInClassInitializer();
-    ExprResult NewInit = SubstExpr(OldInit, TemplateArgs);
 
-    // If the initialization is no longer dependent, check it now.
-    if ((OldField->getType()->isDependentType() || OldInit->isTypeDependent() ||
-         OldInit->isValueDependent()) &&
-        !NewField->getType()->isDependentType() &&
-        !NewInit.get()->isTypeDependent() &&
-        !NewInit.get()->isValueDependent()) {
-      // FIXME: handle list-initialization
-      SourceLocation EqualLoc = NewField->getLocation();
-      NewInit = PerformCopyInitialization(
-        InitializedEntity::InitializeMember(NewField), EqualLoc,
-        NewInit.release());
-
-      if (!NewInit.isInvalid()) {
-        CheckImplicitConversions(NewInit.get(), EqualLoc);
-
-        // C++0x [class.base.init]p7:
-        //   The initialization of each base and member constitutes a
-        //   full-expression.
-        NewInit = MaybeCreateExprWithCleanups(NewInit);
-      }
-    }
-
-    if (NewInit.isInvalid())
+    SourceLocation LParenLoc, RParenLoc;
+    ASTOwningVector<Expr*> NewArgs(*this);
+    if (InstantiateInitializer(OldInit, TemplateArgs, LParenLoc, NewArgs,
+                               RParenLoc))
       NewField->setInvalidDecl();
-    else
-      NewField->setInClassInitializer(NewInit.release());
+    else {
+      assert(NewArgs.size() == 1 && "wrong number of in-class initializers");
+      ActOnCXXInClassMemberInitializer(NewField, LParenLoc, NewArgs[0]);
+    }
   }
 
   if (!FieldsWithMemberInitializers.empty())
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 29385e5..81fd011 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -239,8 +239,6 @@
 /// \brief Instantiate an initializer, breaking it into separate
 /// initialization arguments.
 ///
-/// \param S The semantic analysis object.
-///
 /// \param Init The initializer to instantiate.
 ///
 /// \param TemplateArgs Template arguments to be substituted into the
@@ -249,11 +247,11 @@
 /// \param NewArgs Will be filled in with the instantiation arguments.
 ///
 /// \returns true if an error occurred, false otherwise
-static bool InstantiateInitializer(Sema &S, Expr *Init,
+bool Sema::InstantiateInitializer(Expr *Init,
                             const MultiLevelTemplateArgumentList &TemplateArgs,
-                                   SourceLocation &LParenLoc,
-                                   ASTOwningVector<Expr*> &NewArgs,
-                                   SourceLocation &RParenLoc) {
+                                  SourceLocation &LParenLoc,
+                                  ASTOwningVector<Expr*> &NewArgs,
+                                  SourceLocation &RParenLoc) {
   NewArgs.clear();
   LParenLoc = SourceLocation();
   RParenLoc = SourceLocation();
@@ -273,24 +271,24 @@
   if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
     LParenLoc = ParenList->getLParenLoc();
     RParenLoc = ParenList->getRParenLoc();
-    return S.SubstExprs(ParenList->getExprs(), ParenList->getNumExprs(),
-                        true, TemplateArgs, NewArgs);
+    return SubstExprs(ParenList->getExprs(), ParenList->getNumExprs(),
+                      true, TemplateArgs, NewArgs);
   }
 
   if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) {
     if (!isa<CXXTemporaryObjectExpr>(Construct)) {
-      if (S.SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true,
-                       TemplateArgs, NewArgs))
+      if (SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true,
+                     TemplateArgs, NewArgs))
         return true;
 
       // FIXME: Fake locations!
-      LParenLoc = S.PP.getLocForEndOfToken(Init->getLocStart());
+      LParenLoc = PP.getLocForEndOfToken(Init->getLocStart());
       RParenLoc = LParenLoc;
       return false;
     }
   }
  
-  ExprResult Result = S.SubstExpr(Init, TemplateArgs);
+  ExprResult Result = SubstExpr(Init, TemplateArgs);
   if (Result.isInvalid())
     return true;
 
@@ -386,8 +384,8 @@
     // Instantiate the initializer.
     SourceLocation LParenLoc, RParenLoc;
     ASTOwningVector<Expr*> InitArgs(SemaRef);
-    if (!InstantiateInitializer(SemaRef, D->getInit(), TemplateArgs, LParenLoc,
-                                InitArgs, RParenLoc)) {
+    if (!SemaRef.InstantiateInitializer(D->getInit(), TemplateArgs, LParenLoc,
+                                        InitArgs, RParenLoc)) {
       bool TypeMayContainAuto = true;
       // Attach the initializer to the declaration, if we have one.
       if (InitArgs.size() == 0)
@@ -2689,7 +2687,7 @@
         Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
 
         // Instantiate the initializer.
-        if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs, 
+        if (InstantiateInitializer(Init->getInit(), TemplateArgs, 
                                    LParenLoc, NewArgs, RParenLoc)) {
           AnyErrors = true;
           break;
@@ -2727,7 +2725,7 @@
     }
 
     // Instantiate the initializer.
-    if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs, 
+    if (InstantiateInitializer(Init->getInit(), TemplateArgs, 
                                LParenLoc, NewArgs, RParenLoc)) {
       AnyErrors = true;
       continue;
diff --git a/test/SemaTemplate/member-inclass-init-value-dependent.cpp b/test/SemaTemplate/member-inclass-init-value-dependent.cpp
index d1ae4f2..5bff7f2 100644
--- a/test/SemaTemplate/member-inclass-init-value-dependent.cpp
+++ b/test/SemaTemplate/member-inclass-init-value-dependent.cpp
@@ -9,3 +9,10 @@
   foo<4> bar;
 }
 
+struct S {
+  S(int n);
+};
+template<typename> struct T {
+  S s = 0;
+};
+T<int> t;