[PATCH] D49688: [Sema] Fix a crash when a BlockExpr appears in a default-member-initializer of a class template

Erik Pilkington via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 23 11:43:30 PDT 2018


erik.pilkington created this revision.
erik.pilkington added reviewers: rjmccall, rsmith.
Herald added a subscriber: dexonsmith.

Previously, clang would crash here:

  template <class T> struct S {
    int (^p)() = ^{ return 0; };
  };
  S<int> x;

The problem was that InstantiateClass() was iterating over all the decls(), which included the BlockDecl. The template instantiator doesn't know how to instantiate BlockDecls though, it knows about BlockExprs. This is typically fine because BlockExprs must be the parent of the BlockDecl. To accommodate this, delay instantiating the BlockDecl until we're instantiating the default-member-initializer.

Thanks for taking a look!
Erik


Repository:
  rC Clang

https://reviews.llvm.org/D49688

Files:
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/SemaCXX/instantiate-blocks.cpp


Index: clang/test/SemaCXX/instantiate-blocks.cpp
===================================================================
--- clang/test/SemaCXX/instantiate-blocks.cpp
+++ clang/test/SemaCXX/instantiate-blocks.cpp
@@ -30,3 +30,12 @@
    noret((float)0.0, double(0.0)); // expected-note {{in instantiation of function template specialization 'noret<float, double>' requested here}}
 }
 
+namespace rdar41200624 {
+template <class T>
+struct S {
+  int (^p)() = ^{ return 0; };
+  T (^t)() = ^{ return T{}; };
+  T s = ^{ return T{}; }();
+};
+S<int> x;
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2083,6 +2083,11 @@
     if (Member->getDeclContext() != Pattern)
       continue;
 
+    // BlockDecls can appear in a default-member-initializer. They must be the
+    // child of a BlockExpr, so we only know how to instantiate them from there.
+    if (isa<BlockDecl>(Member))
+      continue;
+
     if (Member->isInvalidDecl()) {
       Instantiation->setInvalidDecl();
       continue;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D49688.156848.patch
Type: text/x-patch
Size: 1157 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180723/392b1633/attachment.bin>


More information about the cfe-commits mailing list