[clang] [Clang] Fix default initializer crash (PR #230520)
Kunal Dubey via cfe-commits
cfe-commits at lists.llvm.org
Sun Oct 11 23:07:25 PDT 2026
https://github.com/xakep8 updated https://github.com/llvm/llvm-project/pull/230520
>From 44b0eae50613dfb1277b54cb34836d68f1a77a38 Mon Sep 17 00:00:00 2001
From: Kunal Dubey <xakep8 at protonmail.com>
Date: Fri, 9 Oct 2026 19:41:54 +0530
Subject: [PATCH 1/2] [Clang] Fix default initializer crash
---
clang/lib/Sema/TreeTransform.h | 7 ++++---
clang/test/SemaCXX/cxx2c-expansion-stmts.cpp | 6 ++++++
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 73367d6bea063..33b334ddfdcf7 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -15295,19 +15295,20 @@ TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
if (!Field)
return ExprError();
+ Expr *RewrittenInit = E->hasRewrittenInit() ? E->getRewrittenExpr() : nullptr;
ExprResult InitRes;
- if (E->hasRewrittenInit()) {
+ if (RewrittenInit) {
// The initializer can refer to `this` and to other members, so it has to
// be transformed in the scope of the field's class.
Sema::CXXThisScopeRAII ThisScope(SemaRef, Field->getParent(), Qualifiers());
- InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
+ InitRes = getDerived().TransformExpr(RewrittenInit);
if (InitRes.isInvalid())
return ExprError();
}
if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
E->getUsedContext() == SemaRef.CurContext &&
- InitRes.get() == E->getRewrittenExpr())
+ InitRes.get() == RewrittenInit)
return E;
return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field,
diff --git a/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp b/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp
index 9045c9b4ae7ae..c195f662597b5 100644
--- a/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp
+++ b/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp
@@ -14,6 +14,11 @@ struct S {
constexpr S(int x) : x{x} {}
};
+struct AggregateWithDefaultInit {
+ int x;
+ int y = 0;
+};
+
void g(int); // #g
template <int n> constexpr int tg() { return n; }
@@ -31,6 +36,7 @@ void f1() {
template for (int x : {1, 2, 3}) g(x);
template for (S x : {1, 2, 3}) g(x.x);
template for (constexpr S x : {1, 2, 3}) tg<x.x>();
+ template for (AggregateWithDefaultInit x : {AggregateWithDefaultInit(1)}) {}
template for (int x : {"1", S(1), {1, 2}}) { // expected-error {{cannot initialize a variable of type 'int' with an lvalue of type 'const char[2]'}} \
expected-error {{no viable conversion from 'S' to 'int'}} \
>From e138a026c9d8adad85949246ebfbb3fd98ed587a Mon Sep 17 00:00:00 2001
From: Kunal Dubey <xakep8 at protonmail.com>
Date: Mon, 12 Oct 2026 11:31:40 +0530
Subject: [PATCH 2/2] [clang] Keep original code shape as per review
---
clang/lib/Sema/TreeTransform.h | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 33b334ddfdcf7..8a071150ea20a 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -15295,20 +15295,19 @@ TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
if (!Field)
return ExprError();
- Expr *RewrittenInit = E->hasRewrittenInit() ? E->getRewrittenExpr() : nullptr;
ExprResult InitRes;
- if (RewrittenInit) {
+ if (E->hasRewrittenInit()) {
// The initializer can refer to `this` and to other members, so it has to
// be transformed in the scope of the field's class.
Sema::CXXThisScopeRAII ThisScope(SemaRef, Field->getParent(), Qualifiers());
- InitRes = getDerived().TransformExpr(RewrittenInit);
+ InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
if (InitRes.isInvalid())
return ExprError();
}
if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
E->getUsedContext() == SemaRef.CurContext &&
- InitRes.get() == RewrittenInit)
+ InitRes.get() == E->getExpr())
return E;
return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field,
More information about the cfe-commits
mailing list