[cfe-dev] Name manging issue with Apple Blocks at global scope

Tom Honermann thonermann at coverity.com
Mon Aug 4 20:33:37 PDT 2014


Thank you for the quick fix!

The update to the test case (cfe/test/CodeGenObjCXX/mangle-blocks.mm) 
revealed something that I wasn't aware of - that mangled names generated 
for local block expressions aren't always assigned numeric 
discriminators local to the declaration context.  In particular, they 
are only assigned local discriminators when required by the target ABI 
for correspondence between entities in multiple translation units.

However, I found that local discriminators are not used when they should 
be when code is first emitted to a .ast file and then compiled. 
Investigation revealed that the problem stems from ASTReader and 
ASTWriter failing to preserve the ManglingNumber and ManglingContextDecl 
members of BlockDecl.

I filed a bug report for this:
Bug 20538 - "Mangled names generated for local types and static objects 
of Block expressions that must correspond across translation units fail 
to do so when .AST files are emitted and loaded"
http://llvm.org/bugs/show_bug.cgi?id=20538

Tom.

On 08/04/2014 02:26 AM, David Majnemer wrote:
> Thanks for the bug report.
>
> This has been fixed in r214699.  In the future, please files bugs here:
> http://llvm.org/bugs/
>
>
> On Sat, Aug 2, 2014 at 6:01 AM, Tom Honermann <thonermann at coverity.com
> <mailto:thonermann at coverity.com>> wrote:
>
>     It appears that BlockDecl instances at global scope are not being
>     given unique names for mangling purposes.  The following test aborts
>     when compiled with Clang trunk (r214613)
>
>     $ cat block-mangling.cpp
>     extern "C" void abort();
>     #define assert(x) ((x) ? (void)0 : abort())
>
>     template<typename T>
>     int tf() {
>          return T::value;
>     }
>
>     int i1 = ^int {
>          struct S { enum { value = 1 };};
>          return tf<S>();
>     }();
>     int i2 = ^int(int p1) {
>          struct S { enum { value = 2 };};
>          return tf<S>() + p1;
>     }(1);
>
>     int main() {
>          assert(i1 == 1);
>          assert(i2 == 3);
>     }
>
>     $ clang -fblocks -std=c++11 block-mangling.cpp -o block-mangling
>     -lBlocksRuntime
>
>     $ ./block-mangling
>     Aborted (core dumped)
>
>     $ nm block-mangling
>     ...
>     0000000000400590 t _Z2tfIZUb_E1SEiv
>     ...
>
>     Note that only one specialization of template function tf() is
>     present in the executable produced.  There should have been two, one
>     for each block literal in the test program.
>
>     The analogous test using C++11 lambda expressions runs as expected.
>
>     $ cat lambda-mangling.cpp
>     extern "C" void abort();
>     #define assert(x) ((x) ? (void)0 : abort())
>
>     template<typename T>
>     int tf() {
>          return T::value;
>     }
>
>     int i1 = [] {
>          struct S { enum { value = 1 };};
>          return tf<S>();
>     }();
>     int i2 = [](int p1) {
>          struct S { enum { value = 2 };};
>          return tf<S>() + p1;
>     }(1);
>
>     int main() {
>          assert(i1 == 1);
>          assert(i2 == 3);
>     }
>
>     $ clang -std=c++11 lambda-mangling.cpp -o lambda-mangling
>
>     $ ./lambda-mangling
>     $ echo $?
>     0
>
>     $ nm lambda-mangling
>     ...
>     0000000000400600 t _Z2tfIZNK3$_0clEvE1SEiv
>     00000000004005f0 t _Z2tfIZNK3$_1clEiE1SEiv
>     ...
>
>     Note that two specializations of template function tf() are present
>     in the lambda case.
>
>     Tom.
>     _________________________________________________
>     cfe-dev mailing list
>     cfe-dev at cs.uiuc.edu <mailto:cfe-dev at cs.uiuc.edu>
>     http://lists.cs.uiuc.edu/__mailman/listinfo/cfe-dev
>     <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev>
>
>



More information about the cfe-dev mailing list