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

Tom Honermann thonermann at coverity.com
Sat Aug 2 06:01:34 PDT 2014


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.



More information about the cfe-dev mailing list