Commit 5b5a111c authored by Richard Smith's avatar Richard Smith Committed by Hans Wennborg
Browse files

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 6d894afd)
parent 4e41127f
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -2173,9 +2173,15 @@ private:
    // constructor.
    ExprResult NewDefArg;
    if (OldParam->hasDefaultArg()) {
      NewDefArg = SemaRef.SubstExpr(OldParam->getDefaultArg(), Args);
      if (NewDefArg.isInvalid())
        return nullptr;
      // We don't care what the value is (we won't use it); just create a
      // placeholder to indicate there is a default argument.
      QualType ParamTy = NewDI->getType();
      NewDefArg = new (SemaRef.Context)
          OpaqueValueExpr(OldParam->getDefaultArg()->getBeginLoc(),
                          ParamTy.getNonLValueExprType(SemaRef.Context),
                          ParamTy->isLValueReferenceType() ? VK_LValue :
                          ParamTy->isRValueReferenceType() ? VK_XValue :
                          VK_RValue);
    }

    ParmVarDecl *NewParam = ParmVarDecl::Create(SemaRef.Context, DC,
+15 −0
Original line number Diff line number Diff line
@@ -507,6 +507,21 @@ umm m(1);

}

namespace PR45124 {
  class a { int d; };
  class b : a {};

  struct x { ~x(); };
  template<typename> class y { y(x = x()); };
  template<typename z> y(z)->y<z>;

  // Not a constant initializer, but trivial default initialization. We won't
  // detect this as trivial default initialization if synthesizing the implicit
  // deduction guide 'template<typename T> y(x = x()) -> Y<T>;' leaves behind a
  // pending cleanup.
  __thread b g;
}

#else

// expected-no-diagnostics