Author: Daniel M. Katz Date: 2024-08-12T13:11:21-04:00 New Revision: c4724f60384917ef0f0e8cc32702fe02c3b3b1c9
URL: https://github.com/llvm/llvm-project/commit/c4724f60384917ef0f0e8cc32702fe02c3b3b1c9 DIFF: https://github.com/llvm/llvm-project/commit/c4724f60384917ef0f0e8cc32702fe02c3b3b1c9.diff LOG: Fix assertion failure during conversion function overload resolution. (#98671) When clang is built with assertions, an otherwise silent (and seemingly innocuous) assertion failure from `SemaConcept.cpp` is triggered by the following program: ```cpp struct S { operator int(); template <typename T> operator T(); }; constexpr auto r = &S::operator int; ``` The function in question compares the "constrained-ness" of `S::operator int` and `S::operator T<int>`; the template kind of the former is `TK_NonTemplate`, whereas the template kind of the later is `TK_FunctionTemplateSpecialization`. The later kind is not "expected" by the function, thus the assertion-failure. Added: clang/test/SemaCXX/PR98671.cpp Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaTemplateDeduction.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 6796a619ba97f8..39e1b0fcb09bbd 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 e9705ec43d86cc..ec951d5ac06dbc 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<CXXConversionDecl>(FD1)); + assert(!FD2->isFunctionTemplateSpecialization() || + isa<CXXConversionDecl>(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<const Expr *, 1> 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 00000000000000..f5051867358852 --- /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 <typename T> + 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 '<overloaded function type>'}} + + +template <typename T> +struct S2 { + template <typename U=T> + S2(U={}) requires (sizeof(T) > 0) {} + // expected-note@-1 {{candidate constructor}} + + template <typename U=T> + S2(U={}) requires (true) {} + // expected-note@-1 {{candidate constructor}} +}; + +S2<int> s; // expected-error {{call to constructor of 'S2<int>' is ambiguous}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits