[LLVMbugs] [Bug 20538] New: 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
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Mon Aug 4 20:17:53 PDT 2014
http://llvm.org/bugs/show_bug.cgi?id=20538
Bug ID: 20538
Summary: 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
Product: clang
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: Frontend
Assignee: unassignedclangbugs at nondot.org
Reporter: thonermann at coverity.com
CC: llvmbugs at cs.uiuc.edu
Classification: Unclassified
The following program exhibits failure of name correspondence for static
objects declared within Block expressions in inline functions when the code is
emitted to a .ast file and then loaded for compilation, rather than being
compiled directly.
$ cat t.h
inline int* f() {
return ^int* {
static int i = 1;
return &i;
}();
}
$ cat t1.cpp
#include "t.h"
int* f1() {
return f();
}
$ cat t2.cpp
int i = ^int { return 1; }();
#include "t.h"
int* f2() {
return f();
}
$ cat main.cpp
extern "C" void abort();
#define assert(x) ((x) ? (void)0 : abort())
extern int* f1();
extern int* f2();
int main() {
assert(f1() == f2());
}
Compiling directly from source, with optimizations, results in a program that
runs as expected.
$ clang -O2 -fblocks t1.cpp t2.cpp main.cpp -o t -lBlocksRuntime
<no error>
$ ./t
<no error>
Emitting to .ast files and then compiling those results in a program that does
not run as expected.
$ clang -O2 -emit-ast -fblocks t1.cpp t2.cpp main.cpp
<no error>
$ clang -O2 -fblocks t1.ast t2.ast main.ast -o t -lBlocksRuntime
<no error>
$ ./t
Aborted (core dumped)
I believe the issue is that serialization via the ASTReader and ASTWriter
classes fails to preserve the BlockDecl class members 'ManglingNumber' and
'ManglingContextDecl'. These variables are referenced (by member functions
getBlockManglingNumber() and getBlockManglingContextDecl()) by various
functions in lib/AST/ItaniumMangle.cpp, but in particular by
CXXNameMangler::mangleUnqualifiedBlock() which contains this code:
1393 void CXXNameMangler::mangleUnqualifiedBlock(const BlockDecl *Block) {
....
1405 // If we have a block mangling number, use it.
1406 unsigned Number = Block->getBlockManglingNumber();
1407 // Otherwise, just make up a number. It doesn't matter what it is
because
1408 // the symbol in question isn't externally visible.
1409 if (!Number)
1410 Number = Context.getBlockId(Block, false);
1411 Out << "Ub";
1412 if (Number > 0)
1413 Out << Number - 1;
1414 Out << '_';
1415 }
These members get their values via calls to the BlockDecl setBlockMangling()
member function which is called by Sema::ActOnBlockStart() when the target ABI
requires name mangling correspondence for an entity across translation units.
Sema::ActOnBlockStart() is called prior to emitting a .ast file (and is not
called again when loading a .ast file). However,
CXXNameMangler::mangleUnqualifiedBlock() and other mangling functions are
called after loading a .ast file. Since serialization fails to preserve the
BlockDecl members mentioned above, mangled names are generated using mangling
numbers and contexts other than what was intended.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20140805/f35a5f93/attachment.html>
More information about the llvm-bugs
mailing list