Author: Matheus Izvekov Date: 2025-01-28T18:08:14-03:00 New Revision: 2cbf2798ae55ddc36aac130df21353fc82891bcf
URL: https://github.com/llvm/llvm-project/commit/2cbf2798ae55ddc36aac130df21353fc82891bcf DIFF: https://github.com/llvm/llvm-project/commit/2cbf2798ae55ddc36aac130df21353fc82891bcf.diff LOG: [clang] fix nondeduced mismatch with nullptr template arguments (#124498) 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. Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/SemaTemplate/cwg2398.cpp Removed: ################################################################################ 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@-1 {{here}} template<template<A*> class TT1> void f(TT1<nullptr>) {} - // new-note@-1 {{here}} template<A*> struct B {}; template void f<B>(B<nullptr>); - // new-error@-1 {{ambiguous}} } // namespace t6 } // namespace nttp_partial_order _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits