From a3a462e5ca57789a5bc9f892f27a4d120f03b4c3 Mon Sep 17 00:00:00 2001 From: Erik Pilkington Date: Mon, 23 Jul 2018 22:47:37 +0000 Subject: [PATCH] [Sema] Fix crash on BlockExprs in a default member initializers Clang would crash when instantiating a BlockDecl that appeared in a default-member-initializer of a class template. Fix this by deferring the instantiation until we instantate the BlockExpr. rdar://41200624 Differential revision: https://reviews.llvm.org/D49688 llvm-svn: 337766 --- clang/lib/Sema/SemaTemplateInstantiate.cpp | 5 +++++ clang/test/SemaCXX/instantiate-blocks.cpp | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 5a4a6bd..3cf5843 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2083,6 +2083,11 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, 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(Member)) + continue; + if (Member->isInvalidDecl()) { Instantiation->setInvalidDecl(); continue; diff --git a/clang/test/SemaCXX/instantiate-blocks.cpp b/clang/test/SemaCXX/instantiate-blocks.cpp index bb0f8d8..dbcef50 100644 --- a/clang/test/SemaCXX/instantiate-blocks.cpp +++ b/clang/test/SemaCXX/instantiate-blocks.cpp @@ -30,3 +30,12 @@ int main(void) noret((float)0.0, double(0.0)); // expected-note {{in instantiation of function template specialization 'noret' requested here}} } +namespace rdar41200624 { +template +struct S { + int (^p)() = ^{ return 0; }; + T (^t)() = ^{ return T{}; }; + T s = ^{ return T{}; }(); +}; +S x; +} -- 2.7.4