[LLVMbugs] [Bug 21910] New: ModuleLinker "chooses" the wrong DISubprogram when linkonce_odr is replaced by weak_odr

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sat Dec 13 11:18:14 PST 2014


http://llvm.org/bugs/show_bug.cgi?id=21910

            Bug ID: 21910
           Summary: ModuleLinker "chooses" the wrong DISubprogram when
                    linkonce_odr is replaced by weak_odr
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: Linker
          Assignee: unassignedbugs at nondot.org
          Reporter: dexonsmith at apple.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

Created attachment 13537
  --> http://llvm.org/bugs/attachment.cgi?id=13537&action=edit
repro.tar.gz: demonstrate mismatched "first subprogram" vs. "chosen subprogram"

When a `linkonce_odr` function gets replaced by a `weak_odr` function, the new
function body's `!dbg` references point at a potentially new DW_TAG_subprogram
in a new DW_TAG_compile_unit.

Some algorithms assume the first `DW_TAG_subprogram` that points at an
`llvm::Function*` is the canonical one, where the first is obtained by walking
compile units in order, and within those, walking their subprograms.  (Maybe it
is?)

Although DW_TAG_subprograms usually de-dup, you can trivially create a
discrepancy by having the `weak_odr` come from a compile_unit that was compiled
in a different directory than the `linkonce_odr`, and linking in the `weak_odr`
version second.

I think (?) the right result would be for the destination module to only
contain one copy of the subprogram, and for it to be the one from the compile
unit that had `weak_odr` linkage.  It's not clear whether that's practical,
though.

Attaching repro.tar.gz, which demonstrates how to create the discrepancy:

$ tar xzf repro.tar.gz
$ cd repro/
$ for f in *.h */*.cpp; do echo "// $f"; cat $f; done
// t.h
template <class T> struct Class {
  int foo() { return 0; }
};
// d1/t1.cpp
#include "t.h"
int foo() { return Class<int>().foo(); }
// d2/t2.cpp
#include "t.h"
template struct Class<int>;
$ make
cd d1 && clang -I.. -c -emit-llvm -gline-tables-only -o t1.bc t1.cpp
cd d2 && clang -I.. -c -emit-llvm -gline-tables-only -o t2.bc t2.cpp
llvm-link -S -o linked.ll d1/t1.bc d2/t2.bc
llvm-link -o linked.bc d1/t1.bc d2/t2.bc
$ grep -e '!dbg !20' linked.ll -B4
define weak_odr i32 @_ZN5ClassIiE3fooEv(%struct.Class* %this) #1 align 2 {
  %1 = alloca %struct.Class*, align 8
  store %struct.Class* %this, %struct.Class** %1, align 8
  %2 = load %struct.Class** %1
  ret i32 0, !dbg !20
$ grep -e '^!20 ' linked.ll 
!20 = metadata !{i32 2, i32 0, metadata !13, null}
$ grep -e '@_ZN5ClassIiE3fooEv, ' linked.ll 
!7 = metadata !{i32 786478, metadata !8, metadata !9, metadata !"foo", metadata
!"foo", metadata !"", i32 2, metadata !6, i1 false, i1 true, i32 0, i32 0,
null, i32 256, i1 false, i32 (%struct.Class*)* @_ZN5ClassIiE3fooEv, null, null,
metadata !2, i32 2}
!13 = metadata !{i32 786478, metadata !14, metadata !15, metadata !"foo",
metadata !"foo", metadata !"", i32 2, metadata !6, i1 false, i1 true, i32 0,
i32 0, null, i32 256, i1 false, i32 (%struct.Class*)* @_ZN5ClassIiE3fooEv,
null, null, metadata !2, i32 2}

-- 
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/20141213/f18fbab3/attachment.html>


More information about the llvm-bugs mailing list