[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