diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 6796a619ba97f..39e1b0fcb09bb 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -217,6 +217,8 @@ Bug Fixes to C++ Support - Clang now preserves the unexpanded flag in a lambda transform used for pack expansion. (#GH56852), (#GH85667), (#GH99877). - Fixed a bug when diagnosing ambiguous explicit specializations of constrained member functions. +- Fixed an assertion failure when selecting a function from an overload set that includes a + specialization of a conversion function template. Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index e9705ec43d86c..ec951d5ac06db 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5805,12 +5805,19 @@ FunctionDecl *Sema::getMoreConstrainedFunction(FunctionDecl *FD1, FunctionDecl *FD2) { assert(!FD1->getDescribedTemplate() && !FD2->getDescribedTemplate() && "not for function templates"); + assert(!FD1->isFunctionTemplateSpecialization() || + isa(FD1)); + assert(!FD2->isFunctionTemplateSpecialization() || + isa(FD2)); + FunctionDecl *F1 = FD1; - if (FunctionDecl *MF = FD1->getInstantiatedFromMemberFunction()) - F1 = MF; + if (FunctionDecl *P = FD1->getTemplateInstantiationPattern(false)) + F1 = P; + FunctionDecl *F2 = FD2; - if (FunctionDecl *MF = FD2->getInstantiatedFromMemberFunction()) - F2 = MF; + if (FunctionDecl *P = FD2->getTemplateInstantiationPattern(false)) + F2 = P; + llvm::SmallVector AC1, AC2; F1->getAssociatedConstraints(AC1); F2->getAssociatedConstraints(AC2); diff --git a/clang/test/SemaCXX/PR98671.cpp b/clang/test/SemaCXX/PR98671.cpp new file mode 100644 index 0000000000000..f505186735885 --- /dev/null +++ b/clang/test/SemaCXX/PR98671.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only %s -verify + +struct S1 { + operator int(); + + template + operator T(); +}; + + +// Ensure that no assertion is raised when overload resolution fails while +// choosing between an operator function template and an operator function. +constexpr auto r = &S1::operator int; +// expected-error@-1 {{initializer of type ''}} + + +template +struct S2 { + template + S2(U={}) requires (sizeof(T) > 0) {} + // expected-note@-1 {{candidate constructor}} + + template + S2(U={}) requires (true) {} + // expected-note@-1 {{candidate constructor}} +}; + +S2 s; // expected-error {{call to constructor of 'S2' is ambiguous}}