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: [email protected]
          Reporter: [email protected]
                CC: [email protected]
    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.
_______________________________________________
LLVMbugs mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/llvmbugs

Reply via email to