r322984 - Allow BlockDecl in CXXRecord scope to have no access specifier.
Richard Trieu via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 19 15:24:03 PST 2018
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/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 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180119/1ec80c64/attachment-0001.html>
More information about the cfe-commits
mailing list