Skip to content

Commit 5b5a111

Browse files
zygoloidzmodem
authored andcommitted
PR45124: Don't leave behind pending cleanups when declaring implicit
deduction guides. Previously if an implicit deduction guide had a default argument with a cleanup, we'd leave the 'pending cleanup' flag set after declaring the implicit guide. But it turns out that there's no reason to even substitute into the default argument when declaring an implicit deduction guide: we only need to record that the default argument exists, not what it is, since we never actually form a call to a deduction guide. (cherry picked from commit 6d894af)
1 parent 4e41127 commit 5b5a111

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,9 +2173,15 @@ struct ConvertConstructorToDeductionGuideTransform {
21732173
// constructor.
21742174
ExprResult NewDefArg;
21752175
if (OldParam->hasDefaultArg()) {
2176-
NewDefArg = SemaRef.SubstExpr(OldParam->getDefaultArg(), Args);
2177-
if (NewDefArg.isInvalid())
2178-
return nullptr;
2176+
// We don't care what the value is (we won't use it); just create a
2177+
// placeholder to indicate there is a default argument.
2178+
QualType ParamTy = NewDI->getType();
2179+
NewDefArg = new (SemaRef.Context)
2180+
OpaqueValueExpr(OldParam->getDefaultArg()->getBeginLoc(),
2181+
ParamTy.getNonLValueExprType(SemaRef.Context),
2182+
ParamTy->isLValueReferenceType() ? VK_LValue :
2183+
ParamTy->isRValueReferenceType() ? VK_XValue :
2184+
VK_RValue);
21792185
}
21802186

21812187
ParmVarDecl *NewParam = ParmVarDecl::Create(SemaRef.Context, DC,

clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,21 @@ umm m(1);
507507

508508
}
509509

510+
namespace PR45124 {
511+
class a { int d; };
512+
class b : a {};
513+
514+
struct x { ~x(); };
515+
template<typename> class y { y(x = x()); };
516+
template<typename z> y(z)->y<z>;
517+
518+
// Not a constant initializer, but trivial default initialization. We won't
519+
// detect this as trivial default initialization if synthesizing the implicit
520+
// deduction guide 'template<typename T> y(x = x()) -> Y<T>;' leaves behind a
521+
// pending cleanup.
522+
__thread b g;
523+
}
524+
510525
#else
511526

512527
// expected-no-diagnostics

0 commit comments

Comments
 (0)