Skip to content

Commit 2cbf279

Browse files
authored
[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.
1 parent ed199c8 commit 2cbf279

File tree

3 files changed

+5
-7
lines changed

3 files changed

+5
-7
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,7 @@ Bug Fixes to C++ Support
10371037
- Fix template argument checking so that converted template arguments are
10381038
converted again. This fixes some issues with partial ordering involving
10391039
template template parameters with non-type template parameters.
1040+
- Fix nondeduced mismatch with nullptr template arguments.
10401041
- Clang now rejects declaring an alias template with the same name as its template parameter. (#GH123423)
10411042
- Fixed the rejection of valid code when referencing an enumerator of an unscoped enum member with a prior declaration. (#GH124405)
10421043
- Fixed immediate escalation of non-dependent expressions. (#GH123405)

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2541,10 +2541,9 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
25412541
return TemplateDeductionResult::NonDeducedMismatch;
25422542

25432543
case TemplateArgument::NullPtr:
2544-
if (A.getKind() == TemplateArgument::NullPtr &&
2545-
S.Context.hasSameType(P.getNullPtrType(), A.getNullPtrType()))
2544+
// 'nullptr' has only one possible value, so it always matches.
2545+
if (A.getKind() == TemplateArgument::NullPtr)
25462546
return TemplateDeductionResult::Success;
2547-
25482547
Info.FirstArg = P;
25492548
Info.SecondArg = A;
25502549
return TemplateDeductionResult::NonDeducedMismatch;
@@ -2559,6 +2558,8 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
25592558
return TemplateDeductionResult::NonDeducedMismatch;
25602559

25612560
case TemplateArgument::StructuralValue:
2561+
// FIXME: structural equality will also compare types,
2562+
// but they should match iff they have the same value.
25622563
if (A.getKind() == TemplateArgument::StructuralValue &&
25632564
A.structurallyEquals(P))
25642565
return TemplateDeductionResult::Success;

clang/test/SemaTemplate/cwg2398.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -697,15 +697,11 @@ namespace nttp_partial_order {
697697
template void f<B>(B<&A::m>);
698698
} // namespace t5
699699
namespace t6 {
700-
// FIXME: This should pick the second overload.
701700
struct A {};
702701
using nullptr_t = decltype(nullptr);
703702
template<template<nullptr_t> class TT2> void f(TT2<nullptr>);
704-
// new-note@-1 {{here}}
705703
template<template<A*> class TT1> void f(TT1<nullptr>) {}
706-
// new-note@-1 {{here}}
707704
template<A*> struct B {};
708705
template void f<B>(B<nullptr>);
709-
// new-error@-1 {{ambiguous}}
710706
} // namespace t6
711707
} // namespace nttp_partial_order

0 commit comments

Comments
 (0)