<div dir="ltr">Hans,<div><br></div><div>I recommend merging this revision into the release.  It fixes an assertion error when mixing modules and blocks.</div><div><br></div><div>Richard</div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 19, 2018 at 12:46 PM, Richard Trieu via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rtrieu<br>
Date: Fri Jan 19 12:46:19 2018<br>
New Revision: 322984<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=322984&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=322984&view=rev</a><br>
Log:<br>
Allow BlockDecl in CXXRecord scope to have no access specifier.<br>
<br>
Using a BlockDecl in a default member initializer causes it to be attached to<br>
CXXMethodDecl without its access specifier being set.  This prevents a crash<br>
where getAccess is called on this BlockDecl, since that method expects any<br>
Decl in CXXRecord scope to have an access specifier.<br>
<br>
Added:<br>
    cfe/trunk/test/Modules/odr_has<wbr>h-blocks.cpp<br>
Modified:<br>
    cfe/trunk/lib/AST/DeclBase.cpp<br>
<br>
Modified: cfe/trunk/lib/AST/DeclBase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=322984&r1=322983&r2=322984&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/AST/DeclBa<wbr>se.cpp?rev=322984&r1=322983&<wbr>r2=322984&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/DeclBase.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Jan 19 12:46:19 2018<br>
@@ -891,12 +891,14 @@ bool Decl::AccessDeclContextSanity(<wbr>) con<br>
   // 4. the context is not a record<br>
   // 5. it's invalid<br>
   // 6. it's a C++0x static_assert.<br>
+  // 7. it's a block literal declaration<br>
   if (isa<TranslationUnitDecl>(this<wbr>) ||<br>
       isa<TemplateTypeParmDecl>(thi<wbr>s) ||<br>
       isa<NonTypeTemplateParmDecl>(<wbr>this) ||<br>
       !isa<CXXRecordDecl>(getDeclCo<wbr>ntext()) ||<br>
       isInvalidDecl() ||<br>
       isa<StaticAssertDecl>(this) ||<br>
+      isa<BlockDecl>(this) ||<br>
       // FIXME: a ParmVarDecl can have ClassTemplateSpecialization<br>
       // as DeclContext (?).<br>
       isa<ParmVarDecl>(this) ||<br>
<br>
Added: cfe/trunk/test/Modules/odr_has<wbr>h-blocks.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash-blocks.cpp?rev=322984&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/Modules/<wbr>odr_hash-blocks.cpp?rev=<wbr>322984&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Modules/odr_has<wbr>h-blocks.cpp (added)<br>
+++ cfe/trunk/test/Modules/odr_has<wbr>h-blocks.cpp Fri Jan 19 12:46:19 2018<br>
@@ -0,0 +1,119 @@<br>
+// Clear and create directories<br>
+// RUN: rm -rf %t<br>
+// RUN: mkdir %t<br>
+// RUN: mkdir %t/cache<br>
+// RUN: mkdir %t/Inputs<br>
+<br>
+// Build first header file<br>
+// RUN: echo "#define FIRST" >> %t/Inputs/first.h<br>
+// RUN: cat %s               >> %t/Inputs/first.h<br>
+<br>
+// Build second header file<br>
+// RUN: echo "#define SECOND" >> %t/Inputs/second.h<br>
+// RUN: cat %s                >> %t/Inputs/second.h<br>
+<br>
+// Test that each header can compile<br>
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 -fblocks %t/Inputs/first.h<br>
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 -fblocks %t/Inputs/second.h<br>
+<br>
+// Build module map file<br>
+// RUN: echo "module FirstModule {"     >> %t/Inputs/module.map<br>
+// RUN: echo "    header \"first.h\""   >> %t/Inputs/module.map<br>
+// RUN: echo "}"                        >> %t/Inputs/module.map<br>
+// RUN: echo "module SecondModule {"    >> %t/Inputs/module.map<br>
+// RUN: echo "    header \"second.h\""  >> %t/Inputs/module.map<br>
+// RUN: echo "}"                        >> %t/Inputs/module.map<br>
+<br>
+// Run test<br>
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \<br>
+// RUN:            -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs \<br>
+// RUN:            -verify %s -std=c++11 -fblocks<br>
+<br>
+#if !defined(FIRST) && !defined(SECOND)<br>
+#include "first.h"<br>
+#include "second.h"<br>
+#endif<br>
+<br>
+// Used for testing<br>
+#if defined(FIRST)<br>
+#define ACCESS public:<br>
+#elif defined(SECOND)<br>
+#define ACCESS private:<br>
+#endif<br>
+<br>
+// TODO: S1, S2, and S3 should generate errors.<br>
+namespace Blocks {<br>
+#if defined(FIRST)<br>
+struct S1 {<br>
+  void (^block)(int x) = ^(int x) { };<br>
+};<br>
+#elif defined(SECOND)<br>
+struct S1 {<br>
+  void (^block)(int x) = ^(int y) { };<br>
+};<br>
+#else<br>
+S1 s1;<br>
+#endif<br>
+<br>
+#if defined(FIRST)<br>
+struct S2 {<br>
+  int (^block)(int x) = ^(int x) { return x + 1; };<br>
+};<br>
+#elif defined(SECOND)<br>
+struct S2 {<br>
+  int (^block)(int x) = ^(int x) { return x; };<br>
+};<br>
+#else<br>
+S2 s2;<br>
+#endif<br>
+<br>
+#if defined(FIRST)<br>
+struct S3 {<br>
+  void run(int (^block)(int x));<br>
+};<br>
+#elif defined(SECOND)<br>
+struct S3 {<br>
+  void run(int (^block)(int x, int y));<br>
+};<br>
+#else<br>
+S3 s3;<br>
+#endif<br>
+<br>
+#define DECLS                                       \<br>
+  int (^block)(int x) = ^(int x) { return x + x; }; \<br>
+  void run(int (^block)(int x, int y));<br>
+<br>
+#if defined(FIRST) || defined(SECOND)<br>
+struct Valid1 {<br>
+  DECLS<br>
+};<br>
+#else<br>
+Valid1 v1;<br>
+#endif<br>
+<br>
+#if defined(FIRST) || defined(SECOND)<br>
+struct Invalid1 {<br>
+  DECLS<br>
+  ACCESS<br>
+};<br>
+#else<br>
+Invalid1 i1;<br>
+// expected-error@second.h:* {{'Blocks::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}<br>
+#endif<br>
+<br>
+#undef DECLS<br>
+}<br>
+<br>
+// Keep macros contained to one file.<br>
+#ifdef FIRST<br>
+#undef FIRST<br>
+#endif<br>
+<br>
+#ifdef SECOND<br>
+#undef SECOND<br>
+#endif<br>
+<br>
+#ifdef ACCESS<br>
+#undef ACCESS<br>
+#endif<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>