[PATCH] D72103: [Sema] Avoid using an invalid InsertPos

Mark de Wever via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 2 10:21:32 PDT 2020


Mordante updated this revision to Diff 282460.
Mordante added a comment.

Rebased the patch and updated the unit tests.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72103/new/

https://reviews.llvm.org/D72103

Files:
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/SemaTemplate/instantiate-var-template.cpp


Index: clang/test/SemaTemplate/instantiate-var-template.cpp
===================================================================
--- clang/test/SemaTemplate/instantiate-var-template.cpp
+++ clang/test/SemaTemplate/instantiate-var-template.cpp
@@ -40,3 +40,68 @@
   template<typename... T> A<T...> models;
   template<> struct B models<>; // expected-error {{incomplete type 'struct B'}} expected-note {{forward declaration}}
 }
+
+namespace PR43221 {
+// This test crashed before so the main reason for the test is to see that it
+// no longer will crash.
+
+template <bool>
+struct enable_if;
+
+template <>
+struct enable_if<true> { using type = void; };
+
+template <typename T, typename = void>
+constexpr bool always_false = false;
+
+// expected-error at +3 {{invalid operands to binary expression}}
+// expected-note at +2 {{in instantiation of member function}}
+template <typename T>
+constexpr bool always_false<T, decltype(foo(T()))> = T() == T();
+
+// expected-note at +2 {{candidate template ignored: substitution failure}}
+template <typename T, typename = typename enable_if<always_false<T>>::type>
+bool operator==(T, T);
+
+// expected-note at +2 {{candidate template ignored: substitution failure}}
+template <typename T, typename = typename enable_if<always_false<T>>::type>
+void data(T);
+
+template <int>
+struct S {};
+// expected-note at +2 {{candidate template ignored: could not match}}
+template <int x>
+constexpr bool operator==(S<x>, S<x>) { return false; }
+
+template <int x>
+constexpr bool s = S<x>() == S<x>() and s<x - 1>;
+
+template <>
+constexpr bool s<0> = S<0>() == S<0>();
+
+void test() { s<127>; } // expected-warning {{expression result unused}}
+
+// expected-note at +2 2 {{while substituting deduced template arguments into function template}}
+template <typename T>
+struct wrapper {
+  wrapper() = default;
+  wrapper(wrapper &&) = default;
+
+  // expected-note at +3 {{in instantiation of variable template specialization}}
+  // expected-note at +2 {{during template argument deduction for variable template partial specialization}}
+  // expected-note at +2 2 {{in instantiation of default argument}}
+  template <typename U, typename = typename enable_if<always_false<U>>::type>
+  explicit wrapper(U);
+
+  // expected-error at +1 {{no matching function for call to 'data'}}
+  friend auto foo(wrapper w) { data(w.m); }
+
+  int m;
+};
+
+// expected-note at +1 2 {{while declaring the implicit copy constructor for}}
+struct wrapper2 {
+  wrapper<void> m;
+};
+
+} // namespace PR43221
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -4465,6 +4465,17 @@
     }
   }
 
+  // The InsertPos needs to be reloaded:
+  // The call to TemplateSpecializationType::anyDependentTemplateArguments
+  // above may call ASTContext::getSubstTemplateTypeParmType. This function
+  // adds a new element in the FoldingSet InsertPos points at. If the
+  // FoldingSet resizes due to this insertion the 'iterator' is no longer
+  // valid.
+  VarTemplateSpecializationDecl *Spec =
+      Template->findSpecialization(Converted, InsertPos);
+  assert(!Spec && "Reloading InsertPos found a template specialization");
+  (void)Spec;
+
   // 2. Create the canonical declaration.
   // Note that we do not instantiate a definition until we see an odr-use
   // in DoMarkVarDeclReferenced().


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D72103.282460.patch
Type: text/x-patch
Size: 3426 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200802/2467c6af/attachment-0001.bin>


More information about the cfe-commits mailing list