<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - nested opaque types confuse the linker"
href="https://bugs.llvm.org/show_bug.cgi?id=38408">38408</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>nested opaque types confuse the linker
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Linker
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>andrew.kaylor@intel.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Given the four input IR files below, the llvm-link should generate a single
defintion of %struct.outer which contains a
pointer to a version of %struct.middle that in turn contains "%struct.inner =
type { i32, i32, %struct.foo* }.
Instead, the linker mistakenly maps %struct.middle to %struct.middle.1 and
produces a second version of %struct.outer
which must be bitcast back to the correct definition in the calls to
use_outer() in the body of f1() and f3().
-=-=-=-=-=-=-=-
File1.ll
-=-=-=-=-=-=-=-
%struct.outer = type { i32, i32, %struct.middle* }
%struct.middle = type opaque
declare void @use_outer(%struct.outer* %o)
define void @f1(%struct.outer* %o) {
call void @use_outer(%struct.outer* %o)
ret void
}
-=-=-=-=-=-=-=-
File2.ll
-=-=-=-=-=-=-=-
%struct.middle.1 = type { %struct.inner.1 }
%struct.inner.1 = type { i32, i32, %struct.bar }
%struct.bar = type { i32, i32 }
define void @use_middle(%struct.middle.1* %m) {
%pbar = getelementptr %struct.middle.1, %struct.middle.1* %m, i64 0, i32 0,
i32 2
call void @use_bar(%struct.bar* %pbar)
ret void
}
define void @use_bar(%struct.bar* %b) {
ret void
}
-=-=-=-=-=-=-=-
File3.ll
-=-=-=-=-=-=-=-
%struct.outer = type { i32, i32, %struct.middle* }
%struct.middle = type { %struct.inner }
%struct.inner = type { i32, i32, %struct.foo* }
%struct.foo = type { i16, i16, i32 }
declare void @use_outer(%struct.outer* %o) {
ret void
}
-=-=-=-=-=-=-=--=-=-=-=-=-=-=--=-=-=-=-=-
llvm-link -S File1.ll File2.ll File3.ll
-=-=-=-=-=-=-=--=-=-=-=-=-=-=--=-=-=-=-=-
%struct.outer = type { i32, i32, %struct.middle* }
%struct.middle = type { %struct.inner.1 }
%struct.inner.1 = type { i32, i32, %struct.bar }
%struct.bar = type { i32, i32 }
%struct.outer.0 = type { i32, i32, %struct.middle.1* }
%struct.middle.1 = type { %struct.inner }
%struct.inner = type { i32, i32, %struct.foo* }
%struct.foo = type { i16, i16, i32 }
define void @f1(%struct.outer* %o) {
call void bitcast (void (%struct.outer.0*)* @use_outer to void
(%struct.outer*)*)(%struct.outer* %o)
ret void
}
define void @use_middle(%struct.middle* %m) {
%pbar = getelementptr %struct.middle, %struct.middle* %m, i64 0, i32 0, i32 2
call void @use_bar(%struct.bar* %pbar)
ret void
}
define void @use_bar(%struct.bar* %b) {
ret void
}
define void @use_outer(%struct.outer.0* %o) {
ret void
}
This also applies to LTO, of course.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>