Thanks! r323108.
On Sat, Jan 20, 2018 at 12:24 AM, Richard Trieu <rtr...@google.com> wrote: > 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/DeclBase.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