[clang] [clang] fix nondeduced mismatch with nullptr template arguments (PR #124498)

Matheus Izvekov via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 28 12:27:45 PST 2025


https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/124498

>From 0e3246e46820df6d13ea623e20c8226c571d4f9a Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Mon, 27 Jan 2025 00:04:59 -0300
Subject: [PATCH] [clang] fix nondeduced mismatch with nullptr template
 arguments

In deduction, when comparing template arguments of value kind,
we should check if the value matches. Values of different types can
still match. For example, `short(0)` matches `int(0)`.

Values of nullptr kind always match each other, since there is only
one such possible value. Similarly to integrals, the type does not
matter.
---
 clang/docs/ReleaseNotes.rst              | 1 +
 clang/lib/Sema/SemaTemplateDeduction.cpp | 7 ++++---
 clang/test/SemaTemplate/cwg2398.cpp      | 4 ----
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c1bf2dc1c33aad..d8a94703bd9c57 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1037,6 +1037,7 @@ Bug Fixes to C++ Support
 - Fix template argument checking so that converted template arguments are
   converted again. This fixes some issues with partial ordering involving
   template template parameters with non-type template parameters.
+- Fix nondeduced mismatch with nullptr template arguments.
 - Clang now rejects declaring an alias template with the same name as its template parameter. (#GH123423)
 - Fixed the rejection of valid code when referencing an enumerator of an unscoped enum member with a prior declaration. (#GH124405)
 - Fixed immediate escalation of non-dependent expressions. (#GH123405)
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 2b96692727a7c8..1e1fce10e7c017 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2541,10 +2541,9 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
     return TemplateDeductionResult::NonDeducedMismatch;
 
   case TemplateArgument::NullPtr:
-    if (A.getKind() == TemplateArgument::NullPtr &&
-        S.Context.hasSameType(P.getNullPtrType(), A.getNullPtrType()))
+    // 'nullptr' has only one possible value, so it always matches.
+    if (A.getKind() == TemplateArgument::NullPtr)
       return TemplateDeductionResult::Success;
-
     Info.FirstArg = P;
     Info.SecondArg = A;
     return TemplateDeductionResult::NonDeducedMismatch;
@@ -2559,6 +2558,8 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
     return TemplateDeductionResult::NonDeducedMismatch;
 
   case TemplateArgument::StructuralValue:
+    // FIXME: structural equality will also compare types,
+    // but they should match iff they have the same value.
     if (A.getKind() == TemplateArgument::StructuralValue &&
         A.structurallyEquals(P))
       return TemplateDeductionResult::Success;
diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp
index 137b94ba2641de..dccb17c48d3256 100644
--- a/clang/test/SemaTemplate/cwg2398.cpp
+++ b/clang/test/SemaTemplate/cwg2398.cpp
@@ -697,15 +697,11 @@ namespace nttp_partial_order {
     template void f<B>(B<&A::m>);
   } // namespace t5
   namespace t6 {
-    // FIXME: This should pick the second overload.
     struct A {};
     using nullptr_t = decltype(nullptr);
     template<template<nullptr_t> class TT2> void f(TT2<nullptr>);
-    // new-note at -1 {{here}}
     template<template<A*>        class TT1> void f(TT1<nullptr>) {}
-    // new-note at -1 {{here}}
     template<A*> struct B {};
     template void f<B>(B<nullptr>);
-    // new-error at -1 {{ambiguous}}
   } // namespace t6
 } // namespace nttp_partial_order



More information about the cfe-commits mailing list