[clang] c4724f6 - Fix assertion failure during conversion function overload resolution. (#98671)

via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 12 10:11:26 PDT 2024


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 at -1 {{initializer of type '<overloaded function type>'}}
+
+
+template <typename T>
+struct S2 {
+  template <typename U=T>
+    S2(U={}) requires (sizeof(T) > 0) {}
+    // expected-note at -1 {{candidate constructor}}
+
+  template <typename U=T>
+    S2(U={}) requires (true) {}
+    // expected-note at -1 {{candidate constructor}}
+};
+
+S2<int> s;  // expected-error {{call to constructor of 'S2<int>' is ambiguous}}


        


More information about the cfe-commits mailing list