[clang] [clang] Correctly handle closures for constructors with consteval default arguments (PR #203554)
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 12 07:53:42 PDT 2026
https://github.com/zmodem created https://github.com/llvm/llvm-project/pull/203554
This is for https://github.com/llvm/llvm-project/issues/201320
Just grabbing the default argument with `getDefaultArg()` during codegen doesn't work if the expression requires evaluating a consteval expression (see bug). Instead, we must properly BuildCXXDefaultArgExpr it during Sema, store it in the AST (including serializatin/deserialization) and then use that during codegen.
>From 43f8ddc6e8bf4ac120c9a3f5e1142ab2cdc32d46 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Fri, 12 Jun 2026 13:26:00 +0200
Subject: [PATCH 1/8] InstantiateDefaultCtorDefaultArgs ->
BuildDefaultArgsForCtorClosure and move to SemaDeclCXX.cpp
---
clang/include/clang/Sema/Sema.h | 7 ++-----
clang/lib/Sema/SemaDecl.cpp | 2 +-
clang/lib/Sema/SemaDeclCXX.cpp | 19 ++++++++++++++++++-
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 18 +-----------------
4 files changed, 22 insertions(+), 24 deletions(-)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b8d760e7e0975..4b972d8bf0516 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14265,11 +14265,8 @@ class Sema final : public SemaBase {
LateInstantiatedAttrVec *LateAttrs = nullptr,
LocalInstantiationScope *OuterMostScope = nullptr);
- /// In the MS ABI, we need to instantiate default arguments of dllexported
- /// default constructors along with the constructor definition. This allows IR
- /// gen to emit a constructor closure which calls the default constructor with
- /// its default arguments.
- void InstantiateDefaultCtorDefaultArgs(CXXConstructorDecl *Ctor);
+ /// XXX: comment
+ void BuildDefaultArgsForCtorClosure(CXXConstructorDecl *Ctor);
bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD,
ParmVarDecl *Param);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index cddcf3a010279..2255d6141db1e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16306,7 +16306,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
Context.getTargetInfo().getCXXABI().isMicrosoft()) {
// If this is an MS ABI dllexport default constructor, instantiate any
// default arguments.
- InstantiateDefaultCtorDefaultArgs(Ctor);
+ BuildDefaultArgsForCtorClosure(Ctor);
}
}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 418ff01f3d98a..f583a765863a4 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6339,7 +6339,7 @@ static void ReferenceDllExportedMembers(Sema &S, CXXRecordDecl *Class) {
if (S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
auto *CD = dyn_cast<CXXConstructorDecl>(MD);
if (CD && CD->isDefaultConstructor() && TSK == TSK_Undeclared) {
- S.InstantiateDefaultCtorDefaultArgs(CD);
+ S.BuildDefaultArgsForCtorClosure(CD);
}
}
@@ -19804,3 +19804,20 @@ void Sema::ActOnFinishFunctionDeclarationDeclarator(Declarator &Declarator) {
}
InventedParameterInfos.pop_back();
}
+
+void Sema::BuildDefaultArgsForCtorClosure(CXXConstructorDecl *Ctor) {
+ assert(Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ Ctor->isDefaultConstructor());
+ unsigned NumParams = Ctor->getNumParams();
+ if (NumParams == 0)
+ return;
+ DLLExportAttr *Attr = Ctor->getAttr<DLLExportAttr>();
+ if (!Attr)
+ return;
+ for (unsigned I = 0; I != NumParams; ++I) {
+ (void)CheckCXXDefaultArgExpr(Attr->getLocation(), Ctor,
+ Ctor->getParamDecl(I));
+ CleanupVarDeclMarking();
+ }
+
+}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 324d6bf3857c7..26ccde0d3315d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1078,22 +1078,6 @@ void Sema::updateAttrsForLateParsedTemplate(const Decl *Pattern, Decl *Inst) {
}
}
-void Sema::InstantiateDefaultCtorDefaultArgs(CXXConstructorDecl *Ctor) {
- assert(Context.getTargetInfo().getCXXABI().isMicrosoft() &&
- Ctor->isDefaultConstructor());
- unsigned NumParams = Ctor->getNumParams();
- if (NumParams == 0)
- return;
- DLLExportAttr *Attr = Ctor->getAttr<DLLExportAttr>();
- if (!Attr)
- return;
- for (unsigned I = 0; I != NumParams; ++I) {
- (void)CheckCXXDefaultArgExpr(Attr->getLocation(), Ctor,
- Ctor->getParamDecl(I));
- CleanupVarDeclMarking();
- }
-}
-
/// Get the previous declaration of a declaration for the purposes of template
/// instantiation. If this finds a previous declaration, then the previous
/// declaration of the instantiation of D should be an instantiation of the
@@ -5961,7 +5945,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// default arguments.
if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
Ctor->isDefaultConstructor()) {
- InstantiateDefaultCtorDefaultArgs(Ctor);
+ BuildDefaultArgsForCtorClosure(Ctor);
}
}
>From 9d30dda8251346958fc6af3df120af53f0cabd79 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Fri, 12 Jun 2026 14:08:37 +0200
Subject: [PATCH 2/8] add Loc and IsCopy params, use it for
CheckCXXThrowOperand too
---
clang/include/clang/Sema/Sema.h | 2 +-
clang/lib/Sema/SemaDecl.cpp | 3 ++-
clang/lib/Sema/SemaDeclCXX.cpp | 24 +++++++++----------
clang/lib/Sema/SemaExprCXX.cpp | 7 +++---
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 3 ++-
5 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4b972d8bf0516..84a124aa076fe 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14266,7 +14266,7 @@ class Sema final : public SemaBase {
LocalInstantiationScope *OuterMostScope = nullptr);
/// XXX: comment
- void BuildDefaultArgsForCtorClosure(CXXConstructorDecl *Ctor);
+ bool BuildDefaultArgsForCtorClosure(SourceLocation Loc, CXXConstructorDecl *Ctor, bool IsCopy = false);
bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD,
ParmVarDecl *Param);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2255d6141db1e..67b91609fb609 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16306,7 +16306,8 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
Context.getTargetInfo().getCXXABI().isMicrosoft()) {
// If this is an MS ABI dllexport default constructor, instantiate any
// default arguments.
- BuildDefaultArgsForCtorClosure(Ctor);
+ if (DLLExportAttr *Attr = Ctor->getAttr<DLLExportAttr>())
+ BuildDefaultArgsForCtorClosure(Attr->getLocation(), Ctor);
}
}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index f583a765863a4..9b8ad2390a60a 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6339,7 +6339,7 @@ static void ReferenceDllExportedMembers(Sema &S, CXXRecordDecl *Class) {
if (S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
auto *CD = dyn_cast<CXXConstructorDecl>(MD);
if (CD && CD->isDefaultConstructor() && TSK == TSK_Undeclared) {
- S.BuildDefaultArgsForCtorClosure(CD);
+ S.BuildDefaultArgsForCtorClosure(CD->getAttr<DLLExportAttr>()->getLocation(), CD);
}
}
@@ -19805,19 +19805,19 @@ void Sema::ActOnFinishFunctionDeclarationDeclarator(Declarator &Declarator) {
InventedParameterInfos.pop_back();
}
-void Sema::BuildDefaultArgsForCtorClosure(CXXConstructorDecl *Ctor) {
- assert(Context.getTargetInfo().getCXXABI().isMicrosoft() &&
- Ctor->isDefaultConstructor());
+bool Sema::BuildDefaultArgsForCtorClosure(SourceLocation Loc, CXXConstructorDecl *Ctor, bool IsCopy) {
+ assert(Context.getTargetInfo().getCXXABI().isMicrosoft());
+
unsigned NumParams = Ctor->getNumParams();
if (NumParams == 0)
- return;
- DLLExportAttr *Attr = Ctor->getAttr<DLLExportAttr>();
- if (!Attr)
- return;
- for (unsigned I = 0; I != NumParams; ++I) {
- (void)CheckCXXDefaultArgExpr(Attr->getLocation(), Ctor,
- Ctor->getParamDecl(I));
- CleanupVarDeclMarking();
+ return false;
+
+ unsigned FirstParam = IsCopy ? 1 : 0;
+ for (unsigned I = FirstParam; I != NumParams; ++I) {
+ if (CheckCXXDefaultArgExpr(Loc, Ctor, Ctor->getParamDecl(I)))
+ return true;
+ CleanupVarDeclMarking(); // XXX: still not sure what this does.
}
+ return false;
}
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 4e1652462b3ae..59e69314c2803 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1070,10 +1070,9 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc,
// We don't keep the instantiated default argument expressions around so
// we must rebuild them here.
- for (unsigned I = 1, E = CD->getNumParams(); I != E; ++I) {
- if (CheckCXXDefaultArgExpr(ThrowLoc, CD, CD->getParamDecl(I)))
- return true;
- }
+ // XXX: surprisingly, CD->isCopyConstructor() is not necessarily true here!
+ if (BuildDefaultArgsForCtorClosure(ThrowLoc, CD, /*IsCopy=*/true))
+ return true;
}
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 26ccde0d3315d..9d21d5f96b020 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5945,7 +5945,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// default arguments.
if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
Ctor->isDefaultConstructor()) {
- BuildDefaultArgsForCtorClosure(Ctor);
+ if (DLLExportAttr *Attr = Ctor->getAttr<DLLExportAttr>())
+ BuildDefaultArgsForCtorClosure(Attr->getLocation(), Ctor);
}
}
>From 89391825c88f8b0abf97f5982fde3cf57a994520 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Fri, 12 Jun 2026 14:31:21 +0200
Subject: [PATCH 3/8] found one more caller; also use BuildCXXDefaultArgExpr
now instead of CheckCXXDefaultArgExpr
---
clang/lib/Sema/SemaDeclCXX.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 9b8ad2390a60a..9de72e94e9ec4 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6392,10 +6392,8 @@ static void checkForMultipleExportedDefaultConstructors(Sema &S,
// If the class is non-dependent, mark the default arguments as ODR-used so
// that we can properly codegen the constructor closure.
if (!Class->isDependentContext()) {
- for (ParmVarDecl *PD : CD->parameters()) {
- (void)S.CheckCXXDefaultArgExpr(Attr->getLocation(), CD, PD);
- S.DiscardCleanupsInEvaluationContext();
- }
+ S.BuildDefaultArgsForCtorClosure(Attr->getLocation(), CD);
+ S.DiscardCleanupsInEvaluationContext();
}
if (LastExportedDefaultCtor) {
@@ -19814,9 +19812,11 @@ bool Sema::BuildDefaultArgsForCtorClosure(SourceLocation Loc, CXXConstructorDecl
unsigned FirstParam = IsCopy ? 1 : 0;
for (unsigned I = FirstParam; I != NumParams; ++I) {
- if (CheckCXXDefaultArgExpr(Loc, Ctor, Ctor->getParamDecl(I)))
+ ExprResult R = BuildCXXDefaultArgExpr(Loc, Ctor, Ctor->getParamDecl(I));
+ if (R.isInvalid())
return true;
- CleanupVarDeclMarking(); // XXX: still not sure what this does.
+
+ CleanupVarDeclMarking();
}
return false;
>From e31da8826f11801af71568cfbf30548c3560f1c2 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Fri, 12 Jun 2026 14:51:49 +0200
Subject: [PATCH 4/8] start adding it to the ast
---
clang/include/clang/AST/DeclCXX.h | 5 +++++
clang/lib/Sema/SemaDeclCXX.cpp | 12 +++++++++---
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index cc4b4ff9db273..ba9036ef65157 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -2668,6 +2668,11 @@ class CXXConstructorDecl final
friend class ASTDeclWriter;
friend TrailingObjects;
+ // FIXME: Just hacking it in here for now.
+ Expr **CtorClosureArgs = nullptr;
+ Expr **ctorClosureArgs() const { return CtorClosureArgs; }
+ void setCtorClosureArgs(Expr **Args) { CtorClosureArgs = Args; }
+
static CXXConstructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
uint64_t AllocKind);
static CXXConstructorDecl *
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 9de72e94e9ec4..8b2286bbd0d23 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -19806,18 +19806,24 @@ void Sema::ActOnFinishFunctionDeclarationDeclarator(Declarator &Declarator) {
bool Sema::BuildDefaultArgsForCtorClosure(SourceLocation Loc, CXXConstructorDecl *Ctor, bool IsCopy) {
assert(Context.getTargetInfo().getCXXABI().isMicrosoft());
+ if (Ctor->ctorClosureArgs())
+ return false;
+
unsigned NumParams = Ctor->getNumParams();
if (NumParams == 0)
return false;
-
unsigned FirstParam = IsCopy ? 1 : 0;
+
+ Expr **Args = new (getASTContext()) Expr*[NumParams - FirstParam];
+
for (unsigned I = FirstParam; I != NumParams; ++I) {
ExprResult R = BuildCXXDefaultArgExpr(Loc, Ctor, Ctor->getParamDecl(I));
+ CleanupVarDeclMarking();
if (R.isInvalid())
return true;
-
- CleanupVarDeclMarking();
+ Args[I - FirstParam] = R.get();
}
+ Ctor->setCtorClosureArgs(Args);
return false;
}
>From decee090a0bfba3e476970a94b920df44917af17 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Fri, 12 Jun 2026 15:48:42 +0200
Subject: [PATCH 5/8] serialize/deserialize the CtorClosureArgs
---
clang/lib/Sema/SemaDeclCXX.cpp | 5 +++--
clang/lib/Serialization/ASTReaderDecl.cpp | 6 ++++++
clang/lib/Serialization/ASTWriterDecl.cpp | 8 ++++++++
3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8b2286bbd0d23..e7a96ad1f390c 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -19814,14 +19814,15 @@ bool Sema::BuildDefaultArgsForCtorClosure(SourceLocation Loc, CXXConstructorDecl
return false;
unsigned FirstParam = IsCopy ? 1 : 0;
- Expr **Args = new (getASTContext()) Expr*[NumParams - FirstParam];
+ Expr **Args = new (getASTContext()) Expr*[NumParams];
+ Args[0] = nullptr;
for (unsigned I = FirstParam; I != NumParams; ++I) {
ExprResult R = BuildCXXDefaultArgExpr(Loc, Ctor, Ctor->getParamDecl(I));
CleanupVarDeclMarking();
if (R.isInvalid())
return true;
- Args[I - FirstParam] = R.get();
+ Args[I] = R.get();
}
Ctor->setCtorClosureArgs(Args);
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index fb291a4b0f2c5..8250b5bdec623 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2333,6 +2333,12 @@ void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
*D->getTrailingObjects<InheritedConstructor>() =
InheritedConstructor(Shadow, Ctor);
}
+ if (int NumCtorClosureArgs = Record.readInt()) {
+ Expr **Args = new (Reader.getContext()) Expr*[NumCtorClosureArgs];
+ for (int I = 0; I != NumCtorClosureArgs; I++)
+ Args[I] = cast<Expr>(Record.readStmt());
+ D->setCtorClosureArgs(Args);
+ }
VisitCXXMethodDecl(D);
}
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 7f5005aa666c7..2ca34561b18a5 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1774,6 +1774,14 @@ void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
Record.AddDeclRef(Inherited.getConstructor());
}
+ if (Expr **CtorClosureArgs = D->ctorClosureArgs()) {
+ Record.push_back(D->getNumParams());
+ for (unsigned I = 0, N = D->getNumParams(); I != N; ++I)
+ Record.AddStmt(CtorClosureArgs[I]);
+ } else {
+ Record.push_back(0);
+ }
+
VisitCXXMethodDecl(D);
Code = serialization::DECL_CXX_CONSTRUCTOR;
}
>From ff475437ab1d81574b333ed7ab7fae3361571d51 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Fri, 12 Jun 2026 16:20:19 +0200
Subject: [PATCH 6/8] use ctorClosureArgs() in getAddrOfCXXCtorClosure()
---
clang/lib/CodeGen/MicrosoftCXXABI.cpp | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 40c7c00d85395..3de3fd8cbe3c8 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -4207,18 +4207,19 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
if (SrcVal)
Args.add(RValue::get(SrcVal), SrcParam->getType());
+
// Add the rest of the default arguments.
SmallVector<const Stmt *, 4> ArgVec;
- ArrayRef<ParmVarDecl *> params = CD->parameters().drop_front(IsCopy ? 1 : 0);
- for (const ParmVarDecl *PD : params) {
- assert(PD->hasDefaultArg() && "ctor closure lacks default args");
- ArgVec.push_back(PD->getDefaultArg());
+ for (unsigned I = IsCopy ? 1 : 0, N = CD->getNumParams(); I != N; ++I) {
+ assert(CD->getParamDecl(I)->hasDefaultArg() && "ctor closure lacks default args");
+ assert(CD->ctorClosureArgs());
+ ArgVec.push_back(CD->ctorClosureArgs()[I]);
}
CodeGenFunction::RunCleanupsScope Cleanups(CGF);
const auto *FPT = CD->getType()->castAs<FunctionProtoType>();
- CGF.EmitCallArgs(Args, FPT, llvm::ArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
+ CGF.EmitCallArgs(Args, FPT, ArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
// Insert any ABI-specific implicit constructor arguments.
AddedStructorArgCounts ExtraArgs =
>From 935c664f56b5ea8da11e883fbbc41434838c31fd Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Fri, 12 Jun 2026 16:25:00 +0200
Subject: [PATCH 7/8] gotta use the canonical ctor decl
---
clang/include/clang/AST/DeclCXX.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index ba9036ef65157..e22881556e2a3 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -2670,8 +2670,8 @@ class CXXConstructorDecl final
// FIXME: Just hacking it in here for now.
Expr **CtorClosureArgs = nullptr;
- Expr **ctorClosureArgs() const { return CtorClosureArgs; }
- void setCtorClosureArgs(Expr **Args) { CtorClosureArgs = Args; }
+ Expr **ctorClosureArgs() const { return getCanonicalDecl()->CtorClosureArgs; }
+ void setCtorClosureArgs(Expr **Args) { getCanonicalDecl()->CtorClosureArgs = Args; }
static CXXConstructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
uint64_t AllocKind);
>From 4461dec7f77f2084b00f089e61e951f96ed42453 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Fri, 12 Jun 2026 16:40:59 +0200
Subject: [PATCH 8/8] tests
---
clang/test/CodeGenCXX/dllexport-ctor-closure.cpp | 9 ++++++++-
clang/test/CodeGenCXX/microsoft-abi-throw.cpp | 13 ++++++++++++-
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/clang/test/CodeGenCXX/dllexport-ctor-closure.cpp b/clang/test/CodeGenCXX/dllexport-ctor-closure.cpp
index 8aeb9b9176fcd..1b4940673f599 100644
--- a/clang/test/CodeGenCXX/dllexport-ctor-closure.cpp
+++ b/clang/test/CodeGenCXX/dllexport-ctor-closure.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++14 \
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++20 \
// RUN: -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases \
// RUN: -disable-llvm-passes -o - %s -w -fms-compatibility-version=19.00 | \
// RUN: FileCheck %s
@@ -95,3 +95,10 @@ struct __declspec(dllexport) ConstexprDefaultArg {
ConstexprDefaultArg(SomeStruct = kConstexprStruct) {}
};
// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FConstexprDefaultArg@@QAEXXZ"
+
+consteval int constEvalFunc() { return 42; }
+struct ConstEvalDefaultArg {
+ __declspec(dllexport) ConstEvalDefaultArg(int n = constEvalFunc()) {}
+};
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FConstEvalDefaultArg@@QAEXXZ"
+// CHECK: call {{.*}} @"??0ConstEvalDefaultArg@@QAE at H@Z"({{.*}}, i32 noundef 42)
diff --git a/clang/test/CodeGenCXX/microsoft-abi-throw.cpp b/clang/test/CodeGenCXX/microsoft-abi-throw.cpp
index 14945ad60f3c1..4fd0df42d8ff5 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-throw.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-throw.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++20 %s -fcxx-exceptions -fms-extensions | FileCheck %s
// CHECK-DAG: @"??_R0?AUY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { ptr @"??_7type_info@@6B@", ptr null, [8 x i8] c".?AUY@@\00" }, comdat
// CHECK-DAG: @"_CT??_R0?AUY@@@8??0Y@@QAE at ABU0@@Z8" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 4, ptr @"??_R0?AUY@@@8", i32 0, i32 -1, i32 0, i32 8, ptr @"??0Y@@QAE at ABU0@@Z" }, section ".xdata", comdat
@@ -71,6 +71,17 @@ void h(Default &d) {
throw d;
}
+consteval int constEvalFunc() { return 123; }
+struct DefaultConstEval {
+ DefaultConstEval(DefaultConstEval&, int = constEvalFunc());
+};
+// CHECK-LABEL: @"??_ODefaultConstEval@@QAEXAAU0@@Z"
+// CHECK: call x86_thiscallcc {{.*}} @"??0DefaultConstEval@@QAE at AAU0@H at Z"({{.*}} %[[this]], {{.*}} %[[src]], i32 noundef 123)
+
+void h2(DefaultConstEval &d) {
+ throw d;
+}
+
struct DeletedCopy {
DeletedCopy();
DeletedCopy(DeletedCopy &&);
More information about the cfe-commits
mailing list