diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5910,7 +5910,9 @@ *this, ExpressionEvaluationContext::PotentiallyEvaluated, Param); ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer = SkipImmediateInvocations; - MarkDeclarationsReferencedInExpr(Init, /*SkipLocalVariables*/ true); + runWithSufficientStackSpace(CallLoc, [&] { + MarkDeclarationsReferencedInExpr(Init, /*SkipLocalVariables*/ true); + }); return false; } @@ -6008,8 +6010,11 @@ ExprEvalContexts.back().DelayedDefaultInitializationContext = { CallLoc, Param, CurContext}; EnsureImmediateInvocationInDefaultArgs Immediate(*this); - ExprResult Res = Immediate.TransformInitializer(Param->getInit(), - /*NotCopy=*/false); + ExprResult Res; + runWithSufficientStackSpace(CallLoc, [&] { + Res = Immediate.TransformInitializer(Param->getInit(), + /*NotCopy=*/false); + }); if (Res.isInvalid()) return ExprError(); Res = ConvertParamDefaultArgument(Param, Res.get(), @@ -6090,9 +6095,11 @@ NestedDefaultChecking; EnsureImmediateInvocationInDefaultArgs Immediate(*this); - ExprResult Res = - Immediate.TransformInitializer(Field->getInClassInitializer(), - /*CXXDirectInit=*/false); + ExprResult Res; + runWithSufficientStackSpace(Loc, [&] { + Res = Immediate.TransformInitializer(Field->getInClassInitializer(), + /*CXXDirectInit=*/false); + }); if (!Res.isInvalid()) Res = ConvertMemberDefaultInitExpression(Field, Res.get(), Loc); if (Res.isInvalid()) { @@ -6105,7 +6112,9 @@ if (Field->getInClassInitializer()) { Expr *E = Init ? Init : Field->getInClassInitializer(); if (!NestedDefaultChecking) - MarkDeclarationsReferencedInExpr(E, /*SkipLocalVariables=*/false); + runWithSufficientStackSpace(Loc, [&] { + MarkDeclarationsReferencedInExpr(E, /*SkipLocalVariables=*/false); + }); // C++11 [class.base.init]p7: // The initialization of each base and member constitutes a // full-expression. diff --git a/clang/test/SemaCXX/cxx11-default-member-initializers.cpp b/clang/test/SemaCXX/cxx11-default-member-initializers.cpp --- a/clang/test/SemaCXX/cxx11-default-member-initializers.cpp +++ b/clang/test/SemaCXX/cxx11-default-member-initializers.cpp @@ -49,3 +49,20 @@ }; } #endif + +// Recursively constructing default member initializers +// should not crash clang. +namespace GH60082 { + +struct A; + +int f(const A&) { return 42; } + +struct A { + int x = f(A()); + A() { } +}; + +void foo() { A(); } + +}