Index: clang/include/clang/AST/Decl.h =================================================================== --- clang/include/clang/AST/Decl.h +++ clang/include/clang/AST/Decl.h @@ -907,6 +907,10 @@ /// declared. unsigned ScopeDepthOrObjCQuals : 7; + /// If this ParmVarDecl is a parameter of a deduction guide. This ensures + /// that we don't profile it the same as the parameter of the constructor. + unsigned IsParamOfDeductionGuide : 1; + /// The number of parameters preceding this parameter in the /// function parameter scope in which it was declared. unsigned ParameterIndex : NumParameterIndexBits; @@ -1544,6 +1548,7 @@ assert(ParmVarDeclBits.DefaultArgKind == DAK_None); assert(ParmVarDeclBits.IsKNRPromoted == false); assert(ParmVarDeclBits.IsObjCMethodParam == false); + assert(ParmVarDeclBits.IsParamOfDeductionGuide == false); setDefaultArg(DefArg); } @@ -1611,6 +1616,13 @@ ParmVarDeclBits.IsKNRPromoted = promoted; } + void setIsParamOfDeductionGuide(bool Value = true) { + ParmVarDeclBits.IsParamOfDeductionGuide = Value; + } + bool isParamOfDeductionGuide() const { + return ParmVarDeclBits.IsParamOfDeductionGuide; + } + Expr *getDefaultArg(); const Expr *getDefaultArg() const { return const_cast(this)->getDefaultArg(); Index: clang/lib/AST/StmtProfile.cpp =================================================================== --- clang/lib/AST/StmtProfile.cpp +++ clang/lib/AST/StmtProfile.cpp @@ -110,6 +110,7 @@ VisitType(Parm->getType()); ID.AddInteger(Parm->getFunctionScopeDepth()); ID.AddInteger(Parm->getFunctionScopeIndex()); + ID.AddBoolean(Parm->isParamOfDeductionGuide()); return; } Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -1880,9 +1880,7 @@ MultiLevelTemplateArgumentList &Args) { TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo(); TypeSourceInfo *NewDI; - if (!Args.getNumLevels()) - NewDI = OldDI; - else if (auto PackTL = OldDI->getTypeLoc().getAs()) { + if (auto PackTL = OldDI->getTypeLoc().getAs()) { // Expand out the one and only element in each inner pack. Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0); NewDI = @@ -1912,9 +1910,7 @@ // constructor. ExprResult NewDefArg; if (OldParam->hasDefaultArg()) { - NewDefArg = Args.getNumLevels() - ? SemaRef.SubstExpr(OldParam->getDefaultArg(), Args) - : OldParam->getDefaultArg(); + NewDefArg = SemaRef.SubstExpr(OldParam->getDefaultArg(), Args); if (NewDefArg.isInvalid()) return nullptr; } @@ -1929,6 +1925,8 @@ NewDefArg.get()); NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(), OldParam->getFunctionScopeIndex()); + NewParam->setIsParamOfDeductionGuide(); + SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); return NewParam; } Index: clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp =================================================================== --- clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp +++ clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp @@ -348,6 +348,22 @@ }; } +namespace rdar41330135 { +template struct A {}; +template +struct S { + template + S(T a, U t, A); +}; +template struct D { + D(T t, A); +}; +int f() { + S s(0, 0, A()); + D d(0, A()); +} +} + #else // expected-no-diagnostics