Skip to content

Commit 0e3246e

Browse files
committed
[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.
1 parent b197268 commit 0e3246e

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)