<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 - rvalue bound to aggregate with base class fails to bind base reference member to temporary"
href="https://bugs.llvm.org/show_bug.cgi?id=42220">42220</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>rvalue bound to aggregate with base class fails to bind base reference member to temporary
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>All
</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>C++17
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>davidfink314@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
</td>
</tr></table>
<p>
<div>
<pre>The following code should bind to the two temporary Obj() and extend their
lifetimes to the lifetimes of the enclosing aggregate.
While the first case (a plain aggregate) succeeds,
the second case (a child aggregate) fails to bind to the temporary Obj(), and
DDDDDDDDDDDDDDDDDDDDDDDDDD is called too early.
The line that fails to bind in the second case is:
DerivedAgg&& x = DerivedAgg{Obj()};
void AAAAAAAAAAAAAAAAAAAAAAAAAA();
void BBBBBBBBBBBBBBBBBBBBBBBB();
void CCCCCCCCCCCCCCCCCCCCCCCCCC();
void DDDDDDDDDDDDDDDDDDDDDDDDDD();
void SEPERATOR();
struct Obj {
inline ~Obj() {
DDDDDDDDDDDDDDDDDDDDDDDDDD();
}
};
struct Agg {
Obj&& obj;
~Agg() {
CCCCCCCCCCCCCCCCCCCCCCCCCC();
}
};
struct DerivedAgg : Agg {
~DerivedAgg() {
BBBBBBBBBBBBBBBBBBBBBBBB();
}
};
int main() {
{
// works, Agg.obj ref binds to Obj(), x binds to Agg
Agg&& x = Agg{Obj()};
AAAAAAAAAAAAAAAAAAAAAAAAAA();
}
SEPERATOR();
{
// fails in clang
// DerivedAgg.Agg.obj should bind to Obj()
// x should bind to DerivedAgg
DerivedAgg&& x = DerivedAgg{Obj()};
AAAAAAAAAAAAAAAAAAAAAAAAAA();
}
}
>From godbolt, clang (trunk), identical to output for clang 8.0.0:
main: # @main
push rbx
sub rsp, 16
call AAAAAAAAAAAAAAAAAAAAAAAAAA()
call CCCCCCCCCCCCCCCCCCCCCCCCCC()
call DDDDDDDDDDDDDDDDDDDDDDDDDD()
call SEPERATOR()
mov rax, rsp
mov qword ptr [rsp + 8], rax
call DDDDDDDDDDDDDDDDDDDDDDDDDD()
call AAAAAAAAAAAAAAAAAAAAAAAAAA()
call BBBBBBBBBBBBBBBBBBBBBBBB()
call CCCCCCCCCCCCCCCCCCCCCCCCCC()
xor eax, eax
add rsp, 16
pop rbx
ret
Compare to gcc 9.1, which gets it right (and MSVC even gets it right too)
main:
push rbp
call AAAAAAAAAAAAAAAAAAAAAAAAAA()
call CCCCCCCCCCCCCCCCCCCCCCCCCC()
call DDDDDDDDDDDDDDDDDDDDDDDDDD()
call SEPERATOR()
call AAAAAAAAAAAAAAAAAAAAAAAAAA()
call BBBBBBBBBBBBBBBBBBBBBBBB()
call CCCCCCCCCCCCCCCCCCCCCCCCCC()
call DDDDDDDDDDDDDDDDDDDDDDDDDD()
xor eax, eax
pop rbp
ret</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>