llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Corentin Jabot (cor3ntin) <details> <summary>Changes</summary> We were not implementing https://eel.is/c++draft/temp.deduct.type#<!-- -->13 properly. Fixes #<!-- -->40328 Assisted-By: Opus 5 --- Full diff: https://github.com/llvm/llvm-project/pull/223645.diff 3 Files Affected: - (modified) clang/docs/ReleaseNotes.md (+3) - (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+16-14) - (modified) clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp (+13) ``````````diff diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 043a0ddae2a6cd..b5dfb5930c3f4b 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -676,6 +676,9 @@ features cannot lower the translation-unit ABI level; class with an invalid non-static data member, such as one qualified with an address space. (#GH194605) +- Fixed deduction of the template parameters appearing in the type of a + constant template parameter of reference type. (#GH40328) + #### Bug Fixes to AST Handling - Fixed a non-deterministic ordering of unused local typedefs that made diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index b66152f2d971d5..795d199ee52243 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -261,6 +261,20 @@ getDeducedNTTParameterFromExpr(TemplateDeductionInfo &Info, Expr *E) { return getDeducedNTTParameterFromExpr(E, Info.getDeducedDepth()); } +/// C++26 [temp.deduct.type]p13: +/// When the value of the argument corresponding to a constant template +/// parameter P that is declared with a dependent type is deduced from an +/// expression, the template parameters in the type of P are deduced from the +/// type of the value. +static QualType getTypeOfTemplateArgumentValue(TemplateDeductionInfo &Info, + const TemplateArgument &A) { + const Expr *E = unwrapExpressionForDeduction(A.getAsExpr()); + if (NonTypeOrVarTemplateParmDecl NTTP = + getDeducedNTTParameterFromExpr(E, Info.getDeducedDepth())) + return NTTP.getType(); + return E->getType(); +} + /// Determine whether two declaration pointers refer to the same /// declaration. static bool isSameDeclaration(Decl *X, Decl *Y) { @@ -497,17 +511,6 @@ DeduceNonTypeTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, if (auto *Expansion = dyn_cast<PackExpansionType>(ParamType)) ParamType = Expansion->getPattern(); - // FIXME: It's not clear how deduction of a parameter of reference - // type from an argument (of non-reference type) should be performed. - // For now, we just make the argument have same reference type as the - // parameter. - if (ParamType->isReferenceType() && !ValueType->isReferenceType()) { - if (ParamType->isRValueReferenceType()) - ValueType = S.Context.getRValueReferenceType(ValueType); - else - ValueType = S.Context.getLValueReferenceType(ValueType); - } - return DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, ParamType, ValueType, Info, Deduced, TDF_SkipNonDependent | TDF_IgnoreQualifiers, @@ -2648,11 +2651,10 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, getDeducedNTTParameterFromExpr(Info, P.getAsExpr())) { switch (A.getKind()) { case TemplateArgument::Expression: { - // The type of the value is the type of the expression as written. return DeduceNonTypeTemplateArgument( S, TemplateParams, NTTP, DeducedTemplateArgument(A), - A.getAsExpr()->IgnoreImplicitAsWritten()->getType(), Info, - PartialOrdering, Deduced, HasDeducedAnyParam); + getTypeOfTemplateArgumentValue(Info, A), Info, PartialOrdering, + Deduced, HasDeducedAnyParam); } case TemplateArgument::Integral: case TemplateArgument::StructuralValue: diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp index 5077d5ff8ad892..a39bb02084aa7c 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp @@ -648,3 +648,16 @@ namespace GH58682 { template <decltype(auto) v> struct B<A<v>> { static constexpr int k = 1; }; static_assert(B<A<(g)>>::k == 1, ""); } // namespace GH58682 + +// C++26 [temp.deduct.type]p13, Example 8. +namespace temp_deduct_type_p13 { + template<long n> struct A { }; + + template<typename T> struct C; + template<typename T, T n> struct C<A<n>> { + using Q = T; + }; + + using R = long; + using R = C<A<2>>::Q; +} // namespace temp_deduct_type_p13 `````````` </details> https://github.com/llvm/llvm-project/pull/223645 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
