Skip to content

Commit f725bb9

Browse files
authored
[clang] Fix CTAD not work for function-type and array-type arguments. (#78159)
Fixes #51710. When transforming a constructor into a corresponding deduction guide, the decayed types (function/array type) were not handled properly which made clang fail to compile valid code. The patch teaches clang handle these decayed type in the transformation.
1 parent cd263a7 commit f725bb9

File tree

3 files changed

+44
-9
lines changed

3 files changed

+44
-9
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,8 @@ Bug Fixes in This Version
748748
- Fix an issue where clang cannot find conversion function with template
749749
parameter when instantiation of template class.
750750
Fixes (`#77583 <https://github.com/llvm/llvm-project/issues/77583>`_)
751+
- Fix an issue where CTAD fails for function-type/array-type arguments.
752+
Fixes (`#51710 <https://github.com/llvm/llvm-project/issues/51710>`_)
751753

752754
Bug Fixes to Compiler Builtins
753755
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,15 +2587,15 @@ struct ConvertConstructorToDeductionGuideTransform {
25872587
: ParamTy->isRValueReferenceType() ? VK_XValue
25882588
: VK_PRValue);
25892589
}
2590-
2591-
ParmVarDecl *NewParam = ParmVarDecl::Create(SemaRef.Context, DC,
2592-
OldParam->getInnerLocStart(),
2593-
OldParam->getLocation(),
2594-
OldParam->getIdentifier(),
2595-
NewDI->getType(),
2596-
NewDI,
2597-
OldParam->getStorageClass(),
2598-
NewDefArg.get());
2590+
// Handle arrays and functions decay.
2591+
auto NewType = NewDI->getType();
2592+
if (NewType->isArrayType() || NewType->isFunctionType())
2593+
NewType = SemaRef.Context.getDecayedType(NewType);
2594+
2595+
ParmVarDecl *NewParam = ParmVarDecl::Create(
2596+
SemaRef.Context, DC, OldParam->getInnerLocStart(),
2597+
OldParam->getLocation(), OldParam->getIdentifier(), NewType, NewDI,
2598+
OldParam->getStorageClass(), NewDefArg.get());
25992599
NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(),
26002600
OldParam->getFunctionScopeIndex());
26012601
SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,4 +645,37 @@ namespace undefined_warnings {
645645
auto test2 = TemplDObj(.0f);
646646
}
647647
}
648+
649+
namespace GH51710 {
650+
template<typename T>
651+
struct A {
652+
A(T f()) {}
653+
A(int f(), T) {}
654+
655+
A(T array[10]) {}
656+
A(int array[10], T) {}
657+
};
658+
659+
template<typename T>
660+
struct B {
661+
B(T array[]) {}
662+
B(int array[], T) {}
663+
};
664+
665+
666+
int foo();
667+
668+
void bar() {
669+
A test1(foo);
670+
A test2(foo, 1);
671+
672+
int array[10];
673+
A test3(array);
674+
A test4(array, 1);
675+
676+
B test5(array);
677+
B test6(array, 1);
678+
}
679+
} // namespace GH51710
680+
648681
#endif

0 commit comments

Comments
 (0)