[clang] d214bec - [clang] Improve deduction of reference typed NTTP (#110393)

via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 1 16:57:49 PDT 2024


Author: Matheus Izvekov
Date: 2024-10-01T20:57:47-03:00
New Revision: d214bec5161e9e6fd9e4c024f6068597822b1d4e

URL: https://github.com/llvm/llvm-project/commit/d214bec5161e9e6fd9e4c024f6068597822b1d4e
DIFF: https://github.com/llvm/llvm-project/commit/d214bec5161e9e6fd9e4c024f6068597822b1d4e.diff

LOG: [clang] Improve deduction of reference typed NTTP (#110393)

This improves the existing workaround for a core issue introduced in
CWG1770.

When performing template argument deduction for an NTTP which the
parameter side is a reference, instead of dropping the references for
both sides, just make the argument be same reference typed as the
parameter, in case the argument is not already a reference type.

Fixes #73460

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaTemplateDeduction.cpp
    clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c351ccff0b6ca0..6e7a5fb76b602b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -465,6 +465,7 @@ Bug Fixes to C++ Support
 - Fixed an assertion failure in debug mode, and potential crashes in release mode, when
   diagnosing a failed cast caused indirectly by a failed implicit conversion to the type of the constructor parameter.
 - Fixed an assertion failure by adjusting integral to boolean vector conversions (#GH108326)
+- Fixed an issue deducing non-type template arguments of reference type. (#GH73460)
 - Mangle friend function templates with a constraint that depends on a template parameter from an enclosing template as members of the enclosing class. (#GH110247)
 - Fixed an issue in constraint evaluation, where type constraints on the lambda expression
   containing outer unexpanded parameters were not correctly expanded. (#GH101754)

diff  --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 0a973a3a0ce036..03ff8145e3b4ac 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -442,18 +442,18 @@ DeduceNonTypeTemplateArgument(Sema &S, TemplateParameterList *TemplateParams,
 
   // 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 remove reference types from both sides and let
-  // the final check for matching types sort out the mess.
-  ValueType = ValueType.getNonReferenceType();
-  if (ParamType->isReferenceType())
-    ParamType = ParamType.getNonReferenceType();
-  else
-    // Top-level cv-qualifiers are irrelevant for a non-reference type.
-    ValueType = ValueType.getUnqualifiedType();
+  // 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_SkipNonDependent | TDF_IgnoreQualifiers,
       PartialOrdering ? PartialOrderingKind::NonCall
                       : PartialOrderingKind::None,
       /*ArrayBound=*/NewDeduced.wasDeducedFromArrayBound(), HasDeducedAnyParam);

diff  --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
index ae06055bf52651..8d9356bb3201cd 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -613,3 +613,11 @@ struct {
 template<typename T>
 using a = s<f(T::x)>;
 }
+
+namespace GH73460 {
+  template <class T, T, T> struct A;
+  template <class T, T n> struct A<T, n, n> {};
+
+  int j;
+  template struct A<int&, j, j>;
+} // namespace GH73460


        


More information about the cfe-commits mailing list