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