[PATCH] D133052: [clang] Avoid crash when expanding conversion templates in concepts.

Luke Nihlen via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 31 13:53:48 PDT 2022


luken-google created this revision.
Herald added a project: All.
luken-google requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Fixes https://github.com/llvm/llvm-project/issues/50891


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133052

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaInit.cpp
  clang/test/SemaTemplate/concepts.cpp


Index: clang/test/SemaTemplate/concepts.cpp
===================================================================
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -256,3 +256,20 @@
 C auto **&j2 = g();  // expected-error {{deduced type 'int' does not satisfy 'C'}}
 C auto **&&j3 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}}
 }
+
+namespace Issue50891 {
+
+template <typename T>
+concept Numeric =
+    requires(T a) {
+        foo(a);
+    };
+
+struct Deferred {
+    friend void foo(Deferred);
+    template <Numeric TO> operator TO();
+};
+
+static_assert(Numeric<Deferred>); // should not crash clang
+
+} // namespace Issue50891
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -22,6 +22,7 @@
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
+#include "clang/Sema/Overload.h"
 #include "clang/Sema/SemaInternal.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/PointerIntPair.h"
@@ -4033,9 +4034,16 @@
 
         FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);
         CXXConversionDecl *Conv;
-        if (ConvTemplate)
+        if (ConvTemplate) {
+          // It is possible with C++20 constraints to cause an infinite template
+          // expansion loop. In those instances the conversion operator has the
+          // same specialized template argument type as the destination type,
+          // and we skip it to avoid the crash.
+          if (Initializer->getType().getCanonicalType() ==
+              DestType.getCanonicalType())
+            continue;
           Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
-        else
+        } else
           Conv = cast<CXXConversionDecl>(D);
 
         if (ConvTemplate)
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -210,7 +210,8 @@
   This fixes `GH51182 <https://github.com/llvm/llvm-project/issues/51182>`
 - Fixes an assert crash caused by looking up missing vtable information on ``consteval``
   virtual functions. Fixes `GH55065 <https://github.com/llvm/llvm-project/issues/55065>`_.
-
+- Fixed a crash during template instantiation on a conversion operator during constraint
+  evaulation. Fixes `GH50891 <https://github.com/llvm/llvm-project/issues/50891>`_.
 
 C++2b Feature Support
 ^^^^^^^^^^^^^^^^^^^^^


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D133052.457082.patch
Type: text/x-patch
Size: 2591 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220831/99fd824a/attachment.bin>


More information about the cfe-commits mailing list