<div dir="ltr">Cool, thanks! Should we also have a test for using a default arg with a pch? Now that ASTContext doesn't have this table any more, it'll work, but maybe it's good to have a regression test for the issue in the PR?</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 23, 2016 at 11:51 AM, Reid Kleckner via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Wed Nov 23 10:51:30 2016<br>
New Revision: 287774<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=287774&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=287774&view=rev</a><br>
Log:<br>
Remove C++ default arg side table for MS ABI ctor closures<br>
<br>
Summary:<br>
We don't need a side table in ASTContext to hold CXXDefaultArgExprs. The<br>
important part of building the CXXDefaultArgExprs was to ODR use the<br>
default argument expressions, not to make AST nodes. Refactor the code<br>
to only check the default argument, and remove the side table in<br>
ASTContext which wasn't being serialized.<br>
<br>
Fixes PR31121<br>
<br>
Reviewers: thakis, rsmith, majnemer<br>
<br>
Subscribers: cfe-commits<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D27007" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D27007</a><br>
<br>
Added:<br>
    cfe/trunk/test/SemaCXX/<wbr>default-arg-closures.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/AST/<wbr>ASTContext.h<br>
    cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
    cfe/trunk/lib/AST/ASTContext.<wbr>cpp<br>
    cfe/trunk/lib/AST/CXXABI.h<br>
    cfe/trunk/lib/AST/<wbr>ItaniumCXXABI.cpp<br>
    cfe/trunk/lib/AST/<wbr>MicrosoftCXXABI.cpp<br>
    cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp<br>
    cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
    cfe/trunk/lib/Sema/<wbr>SemaExprCXX.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/<wbr>ASTContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=287774&r1=287773&r2=287774&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/AST/ASTContext.h?rev=<wbr>287774&r1=287773&r2=287774&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/AST/<wbr>ASTContext.h (original)<br>
+++ cfe/trunk/include/clang/AST/<wbr>ASTContext.h Wed Nov 23 10:51:30 2016<br>
@@ -2452,12 +2452,6 @@ public:<br>
   void addCopyConstructorForException<wbr>Object(CXXRecordDecl *RD,<br>
                                             CXXConstructorDecl *CD);<br>
<br>
-  void addDefaultArgExprForConstructo<wbr>r(const CXXConstructorDecl *CD,<br>
-                                       unsigned ParmIdx, Expr *DAE);<br>
-<br>
-  Expr *<wbr>getDefaultArgExprForConstructo<wbr>r(const CXXConstructorDecl *CD,<br>
-                                        unsigned ParmIdx);<br>
-<br>
   void addTypedefNameForUnnamedTagDec<wbr>l(TagDecl *TD, TypedefNameDecl *TND);<br>
<br>
   TypedefNameDecl *<wbr>getTypedefNameForUnnamedTagDec<wbr>l(const TagDecl *TD);<br>
<br>
Modified: cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=287774&r1=287773&r2=287774&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Sema/Sema.h?rev=287774&<wbr>r1=287773&r2=287774&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/<wbr>Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/<wbr>Sema.h Wed Nov 23 10:51:30 2016<br>
@@ -4408,6 +4408,12 @@ public:<br>
<br>
   ExprResult BuildCXXDefaultInitExpr(<wbr>SourceLocation Loc, FieldDecl *Field);<br>
<br>
+<br>
+  /// Instantiate or parse a C++ default argument expression as necessary.<br>
+  /// Return true on error.<br>
+  bool CheckCXXDefaultArgExpr(<wbr>SourceLocation CallLoc, FunctionDecl *FD,<br>
+                              ParmVarDecl *Param);<br>
+<br>
   /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating<br>
   /// the default expr if needed.<br>
   ExprResult BuildCXXDefaultArgExpr(<wbr>SourceLocation CallLoc,<br>
<br>
Modified: cfe/trunk/lib/AST/ASTContext.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=287774&r1=287773&r2=287774&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>ASTContext.cpp?rev=287774&r1=<wbr>287773&r2=287774&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/ASTContext.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTContext.<wbr>cpp Wed Nov 23 10:51:30 2016<br>
@@ -9172,18 +9172,6 @@ void ASTContext::<wbr>addCopyConstructorForEx<br>
       cast<CXXConstructorDecl>(CD-><wbr>getFirstDecl()));<br>
 }<br>
<br>
-void ASTContext::<wbr>addDefaultArgExprForConstructo<wbr>r(const CXXConstructorDecl *CD,<br>
-                                                 unsigned ParmIdx, Expr *DAE) {<br>
-  ABI-><wbr>addDefaultArgExprForConstructo<wbr>r(<br>
-      cast<CXXConstructorDecl>(CD-><wbr>getFirstDecl()), ParmIdx, DAE);<br>
-}<br>
-<br>
-Expr *ASTContext::<wbr>getDefaultArgExprForConstructo<wbr>r(const CXXConstructorDecl *CD,<br>
-                                                  unsigned ParmIdx) {<br>
-  return ABI-><wbr>getDefaultArgExprForConstructo<wbr>r(<br>
-      cast<CXXConstructorDecl>(CD-><wbr>getFirstDecl()), ParmIdx);<br>
-}<br>
-<br>
 void ASTContext::<wbr>addTypedefNameForUnnamedTagDec<wbr>l(TagDecl *TD,<br>
                                                  TypedefNameDecl *DD) {<br>
   return ABI-><wbr>addTypedefNameForUnnamedTagDec<wbr>l(TD, DD);<br>
<br>
Modified: cfe/trunk/lib/AST/CXXABI.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CXXABI.h?rev=287774&r1=287773&r2=287774&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>CXXABI.h?rev=287774&r1=287773&<wbr>r2=287774&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/CXXABI.h (original)<br>
+++ cfe/trunk/lib/AST/CXXABI.h Wed Nov 23 10:51:30 2016<br>
@@ -54,12 +54,6 @@ public:<br>
   virtual const CXXConstructorDecl *<br>
   getCopyConstructorForException<wbr>Object(CXXRecordDecl *) = 0;<br>
<br>
-  virtual void addDefaultArgExprForConstructo<wbr>r(const CXXConstructorDecl *CD,<br>
-                                               unsigned ParmIdx, Expr *DAE) = 0;<br>
-<br>
-  virtual Expr *<wbr>getDefaultArgExprForConstructo<wbr>r(const CXXConstructorDecl *CD,<br>
-                                                unsigned ParmIdx) = 0;<br>
-<br>
   virtual void addTypedefNameForUnnamedTagDec<wbr>l(TagDecl *TD,<br>
                                                TypedefNameDecl *DD) = 0;<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/<wbr>ItaniumCXXABI.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumCXXABI.cpp?rev=287774&r1=287773&r2=287774&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>ItaniumCXXABI.cpp?rev=287774&<wbr>r1=287773&r2=287774&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/<wbr>ItaniumCXXABI.cpp (original)<br>
+++ cfe/trunk/lib/AST/<wbr>ItaniumCXXABI.cpp Wed Nov 23 10:51:30 2016<br>
@@ -142,14 +142,6 @@ public:<br>
   void addCopyConstructorForException<wbr>Object(CXXRecordDecl *RD,<br>
                                             CXXConstructorDecl *CD) override {}<br>
<br>
-  void addDefaultArgExprForConstructo<wbr>r(const CXXConstructorDecl *CD,<br>
-                                       unsigned ParmIdx, Expr *DAE) override {}<br>
-<br>
-  Expr *<wbr>getDefaultArgExprForConstructo<wbr>r(const CXXConstructorDecl *CD,<br>
-                                        unsigned ParmIdx) override {<br>
-    return nullptr;<br>
-  }<br>
-<br>
   void addTypedefNameForUnnamedTagDec<wbr>l(TagDecl *TD,<br>
                                        TypedefNameDecl *DD) override {}<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/<wbr>MicrosoftCXXABI.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftCXXABI.cpp?rev=287774&r1=287773&r2=287774&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>MicrosoftCXXABI.cpp?rev=<wbr>287774&r1=287773&r2=287774&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/<wbr>MicrosoftCXXABI.cpp (original)<br>
+++ cfe/trunk/lib/AST/<wbr>MicrosoftCXXABI.cpp Wed Nov 23 10:51:30 2016<br>
@@ -67,8 +67,6 @@ public:<br>
 class MicrosoftCXXABI : public CXXABI {<br>
   ASTContext &Context;<br>
   llvm::SmallDenseMap<<wbr>CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor;<br>
-  llvm::SmallDenseMap<std::pair<<wbr>const CXXConstructorDecl *, unsigned>, Expr *><br>
-      CtorToDefaultArgExpr;<br>
<br>
   llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *><br>
       UnnamedTagDeclToDeclaratorDecl<wbr>;<br>
@@ -92,16 +90,6 @@ public:<br>
     llvm_unreachable("unapplicable to the MS ABI");<br>
   }<br>
<br>
-  void addDefaultArgExprForConstructo<wbr>r(const CXXConstructorDecl *CD,<br>
-                                       unsigned ParmIdx, Expr *DAE) override {<br>
-    CtorToDefaultArgExpr[std::<wbr>make_pair(CD, ParmIdx)] = DAE;<br>
-  }<br>
-<br>
-  Expr *<wbr>getDefaultArgExprForConstructo<wbr>r(const CXXConstructorDecl *CD,<br>
-                                        unsigned ParmIdx) override {<br>
-    return CtorToDefaultArgExpr[std::<wbr>make_pair(CD, ParmIdx)];<br>
-  }<br>
-<br>
   const CXXConstructorDecl *<br>
   getCopyConstructorForException<wbr>Object(CXXRecordDecl *RD) override {<br>
     return RecordToCopyCtor[RD];<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=287774&r1=287773&r2=287774&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp?rev=<wbr>287774&r1=287773&r2=287774&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp Wed Nov 23 10:51:30 2016<br>
@@ -3869,11 +3869,11 @@ MicrosoftCXXABI::<wbr>getAddrOfCXXCtorClosure<br>
     Args.add(RValue::get(SrcVal), SrcParam.getType());<br>
<br>
   // Add the rest of the default arguments.<br>
-  std::vector<Stmt *> ArgVec;<br>
-  for (unsigned I = IsCopy ? 1 : 0, E = CD->getNumParams(); I != E; ++I) {<br>
-    Stmt *DefaultArg = getContext().<wbr>getDefaultArgExprForConstructo<wbr>r(CD, I);<br>
-    assert(DefaultArg && "sema forgot to instantiate default args");<br>
-    ArgVec.push_back(DefaultArg);<br>
+  SmallVector<const Stmt *, 4> ArgVec;<br>
+  ArrayRef<ParmVarDecl *> params = CD->parameters().drop_front(<wbr>IsCopy ? 1 : 0);<br>
+  for (const ParmVarDecl *PD : params) {<br>
+    assert(PD->hasDefaultArg() && "ctor closure lacks default args");<br>
+    ArgVec.push_back(PD-><wbr>getDefaultArg());<br>
   }<br>
<br>
   CodeGenFunction::<wbr>RunCleanupsScope Cleanups(CGF);<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=287774&r1=287773&r2=287774&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp?rev=287774&r1=<wbr>287773&r2=287774&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp Wed Nov 23 10:51:30 2016<br>
@@ -10365,7 +10365,7 @@ void Sema::<wbr>ActOnFinishCXXMemberDecls() {<br>
   }<br>
 }<br>
<br>
-static void getDefaultArgExprsForConstruct<wbr>ors(Sema &S, CXXRecordDecl *Class) {<br>
+static void checkDefaultArgExprsForConstru<wbr>ctors(Sema &S, CXXRecordDecl *Class) {<br>
   // Don't do anything for template patterns.<br>
   if (Class-><wbr>getDescribedClassTemplate())<br>
     return;<br>
@@ -10379,7 +10379,7 @@ static void getDefaultArgExprsForConstru<br>
     if (!CD) {<br>
       // Recurse on nested classes.<br>
       if (auto *NestedRD = dyn_cast<CXXRecordDecl>(<wbr>Member))<br>
-        getDefaultArgExprsForConstruct<wbr>ors(S, NestedRD);<br>
+        checkDefaultArgExprsForConstru<wbr>ctors(S, NestedRD);<br>
       continue;<br>
     } else if (!CD->isDefaultConstructor() || !CD->hasAttr<DLLExportAttr>()) {<br>
       continue;<br>
@@ -10404,14 +10404,9 @@ static void getDefaultArgExprsForConstru<br>
     LastExportedDefaultCtor = CD;<br>
<br>
     for (unsigned I = 0; I != NumParams; ++I) {<br>
-      // Skip any default arguments that we've already instantiated.<br>
-      if (S.Context.<wbr>getDefaultArgExprForConstructo<wbr>r(CD, I))<br>
-        continue;<br>
-<br>
-      Expr *DefaultArg = S.BuildCXXDefaultArgExpr(<wbr>Class->getLocation(), CD,<br>
-                                                  CD->getParamDecl(I)).get();<br>
+      (void)S.<wbr>CheckCXXDefaultArgExpr(Class-><wbr>getLocation(), CD,<br>
+                                     CD->getParamDecl(I));<br>
       S.<wbr>DiscardCleanupsInEvaluationCon<wbr>text();<br>
-      S.Context.<wbr>addDefaultArgExprForConstructo<wbr>r(CD, I, DefaultArg);<br>
     }<br>
   }<br>
 }<br>
@@ -10423,7 +10418,7 @@ void Sema::<wbr>ActOnFinishCXXNonNestedClass(<br>
   // have default arguments or don't use the standard calling convention are<br>
   // wrapped with a thunk called the default constructor closure.<br>
   if (RD && Context.getTargetInfo().<wbr>getCXXABI().isMicrosoft())<br>
-    getDefaultArgExprsForConstruct<wbr>ors(*this, RD);<br>
+    checkDefaultArgExprsForConstru<wbr>ctors(*this, RD);<br>
<br>
   referenceDLLExportedClassMetho<wbr>ds();<br>
 }<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=287774&r1=287773&r2=287774&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaExpr.cpp?rev=287774&r1=<wbr>287773&r2=287774&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp Wed Nov 23 10:51:30 2016<br>
@@ -4513,16 +4513,15 @@ Sema::<wbr>CreateBuiltinArraySubscriptExp<wbr>r(Ex<br>
       ArraySubscriptExpr(LHSExp, RHSExp, ResultType, VK, OK, RLoc);<br>
 }<br>
<br>
-ExprResult Sema::BuildCXXDefaultArgExpr(<wbr>SourceLocation CallLoc,<br>
-                                        FunctionDecl *FD,<br>
-                                        ParmVarDecl *Param) {<br>
+bool Sema::CheckCXXDefaultArgExpr(<wbr>SourceLocation CallLoc, FunctionDecl *FD,<br>
+                                  ParmVarDecl *Param) {<br>
   if (Param->hasUnparsedDefaultArg(<wbr>)) {<br>
     Diag(CallLoc,<br>
          diag::err_use_of_default_<wbr>argument_to_function_declared_<wbr>later) <<<br>
       FD << cast<CXXRecordDecl>(FD-><wbr>getDeclContext())-><wbr>getDeclName();<br>
     Diag(UnparsedDefaultArgLocs[<wbr>Param],<br>
          diag::note_default_argument_<wbr>declared_here);<br>
-    return ExprError();<br>
+    return true;<br>
   }<br>
<br>
   if (Param-><wbr>hasUninstantiatedDefaultArg()) {<br>
@@ -4538,11 +4537,11 @@ ExprResult Sema::BuildCXXDefaultArgExpr(<br>
     InstantiatingTemplate Inst(*this, CallLoc, Param,<br>
                                MutiLevelArgList.getInnermost(<wbr>));<br>
     if (Inst.isInvalid())<br>
-      return ExprError();<br>
+      return true;<br>
     if (Inst.isAlreadyInstantiating()<wbr>) {<br>
       Diag(Param->getLocStart(), diag::err_recursive_default_<wbr>argument) << FD;<br>
       Param->setInvalidDecl();<br>
-      return ExprError();<br>
+      return true;<br>
     }<br>
<br>
     ExprResult Result;<br>
@@ -4557,7 +4556,7 @@ ExprResult Sema::BuildCXXDefaultArgExpr(<br>
                                 /*DirectInit*/false);<br>
     }<br>
     if (Result.isInvalid())<br>
-      return ExprError();<br>
+      return true;<br>
<br>
     // Check the expression as an initializer for the parameter.<br>
     InitializedEntity Entity<br>
@@ -4570,12 +4569,12 @@ ExprResult Sema::BuildCXXDefaultArgExpr(<br>
     InitializationSequence InitSeq(*this, Entity, Kind, ResultE);<br>
     Result = InitSeq.Perform(*this, Entity, Kind, ResultE);<br>
     if (Result.isInvalid())<br>
-      return ExprError();<br>
+      return true;<br>
<br>
     Result = ActOnFinishFullExpr(Result.<wbr>getAs<Expr>(),<br>
                                  Param->getOuterLocStart());<br>
     if (Result.isInvalid())<br>
-      return ExprError();<br>
+      return true;<br>
<br>
     // Remember the instantiated default argument.<br>
     Param->setDefaultArg(Result.<wbr>getAs<Expr>());<br>
@@ -4588,7 +4587,7 @@ ExprResult Sema::BuildCXXDefaultArgExpr(<br>
   if (!Param->hasInit()) {<br>
     Diag(Param->getLocStart(), diag::err_recursive_default_<wbr>argument) << FD;<br>
     Param->setInvalidDecl();<br>
-    return ExprError();<br>
+    return true;<br>
   }<br>
<br>
   // If the default expression creates temporaries, we need to<br>
@@ -4615,9 +4614,15 @@ ExprResult Sema::BuildCXXDefaultArgExpr(<br>
   // as being "referenced".<br>
   MarkDeclarationsReferencedInEx<wbr>pr(Param->getDefaultArg(),<br>
                                    /*SkipLocalVariables=*/true);<br>
-  return CXXDefaultArgExpr::Create(<wbr>Context, CallLoc, Param);<br>
+  return false;<br>
 }<br>
<br>
+ExprResult Sema::BuildCXXDefaultArgExpr(<wbr>SourceLocation CallLoc,<br>
+                                        FunctionDecl *FD, ParmVarDecl *Param) {<br>
+  if (CheckCXXDefaultArgExpr(<wbr>CallLoc, FD, Param))<br>
+    return ExprError();<br>
+  return CXXDefaultArgExpr::Create(<wbr>Context, CallLoc, Param);<br>
+}<br>
<br>
 Sema::VariadicCallType<br>
 Sema::getVariadicCallType(<wbr>FunctionDecl *FDecl, const FunctionProtoType *Proto,<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>SemaExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=287774&r1=287773&r2=287774&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaExprCXX.cpp?rev=287774&r1=<wbr>287773&r2=287774&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>SemaExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>SemaExprCXX.cpp Wed Nov 23 10:51:30 2016<br>
@@ -863,13 +863,8 @@ bool Sema::CheckCXXThrowOperand(<wbr>SourceLo<br>
       // We don't keep the instantiated default argument expressions around so<br>
       // we must rebuild them here.<br>
       for (unsigned I = 1, E = CD->getNumParams(); I != E; ++I) {<br>
-        // Skip any default arguments that we've already instantiated.<br>
-        if (Context.<wbr>getDefaultArgExprForConstructo<wbr>r(CD, I))<br>
-          continue;<br>
-<br>
-        Expr *DefaultArg =<br>
-            BuildCXXDefaultArgExpr(<wbr>ThrowLoc, CD, CD->getParamDecl(I)).get();<br>
-        Context.<wbr>addDefaultArgExprForConstructo<wbr>r(CD, I, DefaultArg);<br>
+        if (CheckCXXDefaultArgExpr(<wbr>ThrowLoc, CD, CD->getParamDecl(I)))<br>
+          return true;<br>
       }<br>
     }<br>
   }<br>
<br>
Added: cfe/trunk/test/SemaCXX/<wbr>default-arg-closures.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/default-arg-closures.cpp?rev=287774&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaCXX/default-arg-closures.<wbr>cpp?rev=287774&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/<wbr>default-arg-closures.cpp (added)<br>
+++ cfe/trunk/test/SemaCXX/<wbr>default-arg-closures.cpp Wed Nov 23 10:51:30 2016<br>
@@ -0,0 +1,45 @@<br>
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions -fms-extensions -verify %s -std=c++11<br>
+<br>
+// The MS ABI has a few ways to generate constructor closures, which require<br>
+// instantiating and checking the semantics of default arguments. Make sure we<br>
+// do that right.<br>
+<br>
+// FIXME: Don't diagnose this issue twice.<br>
+template <typename T><br>
+struct DependentDefaultCtorArg { // expected-note {{in instantiation of default function argument}}<br>
+  // expected-error@+1 2 {{type 'int' cannot be used prior to '::' because it has no members}}<br>
+  DependentDefaultCtorArg(int n = T::error);<br>
+};<br>
+struct<br>
+__declspec(dllexport) // expected-note {{due to 'ExportDefaultCtorClosure' being dllexported}}<br>
+ExportDefaultCtorClosure // expected-note {{implicit default constructor for 'ExportDefaultCtorClosure' first required here}}<br>
+: DependentDefaultCtorArg<int> // expected-note {{in instantiation of template class}}<br>
+{};<br>
+<br>
+template <typename T><br>
+struct DependentDefaultCopyArg {<br>
+  DependentDefaultCopyArg() {}<br>
+  // expected-error@+1 {{type 'int' cannot be used prior to '::' because it has no members}}<br>
+  DependentDefaultCopyArg(const DependentDefaultCopyArg &o, int n = T::member) {}<br>
+};<br>
+<br>
+struct HasMember {<br>
+  enum { member = 0 };<br>
+};<br>
+void UseDependentArg() { throw DependentDefaultCopyArg<<wbr>HasMember>(); }<br>
+<br>
+void ErrorInDependentArg() {<br>
+  throw DependentDefaultCopyArg<int>()<wbr>; // expected-note {{required here}}<br>
+}<br>
+<br>
+struct HasCleanup {<br>
+  ~HasCleanup();<br>
+};<br>
+<br>
+struct Default {<br>
+  Default(const Default &o, int d = (HasCleanup(), 42));<br>
+};<br>
+<br>
+void f(const Default &d) {<br>
+  throw d;<br>
+}<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>