diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 174392da1755..ea57769a4a57 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -748,6 +748,8 @@ Bug Fixes in This Version - Fix an issue where clang cannot find conversion function with template parameter when instantiation of template class. Fixes (`#77583 `_) +- Fix an issue where CTAD fails for function-type/array-type arguments. + Fixes (`#51710 `_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 5fcc39ec7005..80a48c268a64 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2587,15 +2587,15 @@ private: : ParamTy->isRValueReferenceType() ? VK_XValue : VK_PRValue); } + // Handle arrays and functions decay. + auto NewType = NewDI->getType(); + if (NewType->isArrayType() || NewType->isFunctionType()) + NewType = SemaRef.Context.getDecayedType(NewType); - ParmVarDecl *NewParam = ParmVarDecl::Create(SemaRef.Context, DC, - OldParam->getInnerLocStart(), - OldParam->getLocation(), - OldParam->getIdentifier(), - NewDI->getType(), - NewDI, - OldParam->getStorageClass(), - NewDefArg.get()); + ParmVarDecl *NewParam = ParmVarDecl::Create( + SemaRef.Context, DC, OldParam->getInnerLocStart(), + OldParam->getLocation(), OldParam->getIdentifier(), NewType, NewDI, + OldParam->getStorageClass(), NewDefArg.get()); NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(), OldParam->getFunctionScopeIndex()); SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp index a490d318f54b..33ed4295c2e4 100644 --- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp +++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp @@ -645,4 +645,37 @@ namespace undefined_warnings { auto test2 = TemplDObj(.0f); } } + +namespace GH51710 { +template +struct A { + A(T f()) {} + A(int f(), T) {} + + A(T array[10]) {} + A(int array[10], T) {} +}; + +template +struct B { + B(T array[]) {} + B(int array[], T) {} +}; + + +int foo(); + +void bar() { + A test1(foo); + A test2(foo, 1); + + int array[10]; + A test3(array); + A test4(array, 1); + + B test5(array); + B test6(array, 1); +} +} // namespace GH51710 + #endif