When using a default function argument for a function template (or
member function thereof), perform the template instantiation each time
the default argument is needed. This ensures that
  (1) We get different CXXTemporary objects for each instantiation, and
  (2) Any other instantiations or definitions triggered by the
  instantiation of the default argument expression are guaranteed to
  happen; previously, they might have been suppressed, e.g., because
  they happened in an unevaluated context.

This fixes the majority of PR5810. However, it does not address the
problem where we may have multiple uses of the same CXXTemporary
within an expression when the temporary came from a non-instantiated
default argument expression.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92015 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 5444a77..e4538fd 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -352,6 +352,19 @@
   }
 }
 
+CXXDefaultArgExpr *
+CXXDefaultArgExpr::Create(ASTContext &C, ParmVarDecl *Param, Expr *SubExpr) {
+  void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *));
+  return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Param, SubExpr);
+}
+
+void CXXDefaultArgExpr::DoDestroy(ASTContext &C) {
+  if (Param.getInt())
+    getExpr()->Destroy(C);
+  this->~CXXDefaultArgExpr();
+  C.Deallocate(this);
+}
+
 CXXTemporary *CXXTemporary::Create(ASTContext &C,
                                    const CXXDestructorDecl *Destructor) {
   return new (C) CXXTemporary(Destructor);
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 09e1d6f..c56eeef 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3078,15 +3078,30 @@
       if (Result.isInvalid())
         return ExprError();
 
-      if (SetParamDefaultArgument(Param, move(Result),
-                                  /*FIXME:EqualLoc*/
-                                  UninstExpr->getSourceRange().getBegin()))
+      // Check the expression as an initializer for the parameter.
+      InitializedEntity Entity
+        = InitializedEntity::InitializeParameter(Param);
+      InitializationKind Kind
+        = InitializationKind::CreateCopy(Param->getLocation(),
+               /*FIXME:EqualLoc*/UninstExpr->getSourceRange().getBegin());
+      Expr *ResultE = Result.takeAs<Expr>();
+
+      InitializationSequence InitSeq(*this, Entity, Kind, &ResultE, 1);
+      Result = InitSeq.Perform(*this, Entity, Kind, 
+                               MultiExprArg(*this, (void**)&ResultE, 1));
+      if (Result.isInvalid())
         return ExprError();
+      
+      // Build the default argument expression.
+      return Owned(CXXDefaultArgExpr::Create(Context, Param,
+                                             Result.takeAs<Expr>()));
     }
 
     // If the default expression creates temporaries, we need to
     // push them to the current stack of expression temporaries so they'll
     // be properly destroyed.
+    // FIXME: We should really be rebuilding the default argument with new
+    // bound temporaries; see the comment in PR5810.
     for (unsigned i = 0, e = Param->getNumDefaultArgTemporaries(); i != e; ++i)
       ExprTemporaries.push_back(Param->getDefaultArgTemporary(i));
   }