Skip to content

Commit a06cdbc

Browse files
committed
[clang] Improve deduction of reference typed NTTP
This improves the existing workaround for a core issue introduced in CWG1770. When performing template argument deduction for an NNTP which the parameter side is a reference, instead of dropping the references for both sides, just make the argument be same reference typed as the parameter, in case the argument is not already a reference type. Fixes #73460
1 parent 2575c39 commit a06cdbc

File tree

3 files changed

+18
-9
lines changed

3 files changed

+18
-9
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ Bug Fixes to C++ Support
446446
- Fixed an assertion failure in debug mode, and potential crashes in release mode, when
447447
diagnosing a failed cast caused indirectly by a failed implicit conversion to the type of the constructor parameter.
448448
- Fixed an assertion failure by adjusting integral to boolean vector conversions (#GH108326)
449+
- Fixed an issue deducing non-type template arguments of reference type. (#GH73460)
449450

450451
Bug Fixes to AST Handling
451452
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -440,18 +440,18 @@ DeduceNonTypeTemplateArgument(Sema &S, TemplateParameterList *TemplateParams,
440440

441441
// FIXME: It's not clear how deduction of a parameter of reference
442442
// type from an argument (of non-reference type) should be performed.
443-
// For now, we just remove reference types from both sides and let
444-
// the final check for matching types sort out the mess.
445-
ValueType = ValueType.getNonReferenceType();
446-
if (ParamType->isReferenceType())
447-
ParamType = ParamType.getNonReferenceType();
448-
else
449-
// Top-level cv-qualifiers are irrelevant for a non-reference type.
450-
ValueType = ValueType.getUnqualifiedType();
443+
// For now, we just make the argument have same reference type as the
444+
// parameter.
445+
if (ParamType->isReferenceType() && !ValueType->isReferenceType()) {
446+
if (ParamType->isRValueReferenceType())
447+
ValueType = S.Context.getRValueReferenceType(ValueType);
448+
else
449+
ValueType = S.Context.getLValueReferenceType(ValueType);
450+
}
451451

452452
return DeduceTemplateArgumentsByTypeMatch(
453453
S, TemplateParams, ParamType, ValueType, Info, Deduced,
454-
TDF_SkipNonDependent,
454+
TDF_SkipNonDependent | TDF_IgnoreQualifiers,
455455
PartialOrdering ? PartialOrderingKind::NonCall
456456
: PartialOrderingKind::None,
457457
/*ArrayBound=*/NewDeduced.wasDeducedFromArrayBound(), HasDeducedAnyParam);

clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,3 +613,11 @@ struct {
613613
template<typename T>
614614
using a = s<f(T::x)>;
615615
}
616+
617+
namespace GH73460 {
618+
template <class T, T, T> struct A;
619+
template <class T, T n> struct A<T, n, n> {};
620+
621+
int j;
622+
template struct A<int&, j, j>;
623+
} // namespace GH73460

0 commit comments

Comments
 (0)