<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>