r322984 - Allow BlockDecl in CXXRecord scope to have no access specifier.

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 22 04:56:13 PST 2018


Thanks! r323108.

On Sat, Jan 20, 2018 at 12:24 AM, Richard Trieu <rtrieu at 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 at 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 at second.h:* {{'Blocks::Invalid1' has different
>> definitions in different modules; first difference is definition in module
>> 'SecondModule' found private access specifier}}
>> +// expected-note at 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 at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>


More information about the cfe-commits mailing list