Skip to content

Commit

Permalink
[clang] fix nondeduced mismatch with nullptr template arguments
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mizvekov committed Jan 27, 2025
1 parent 7b4befe commit e8ded39
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 7 deletions.
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,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.

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/Sema/SemaTemplateDeduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
4 changes: 0 additions & 4 deletions clang/test/SemaTemplate/cwg2398.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit e8ded39

Please sign in to comment.