<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p><br>
</p>
<div class="moz-cite-prefix">On 7/31/20 5:59 PM, James Y Knight
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CAA2zVHrPOXHYFK7NmGRd1o8V_=7AZVA=et4AipTOHY5dpwbENA@mail.gmail.com">
<div dir="ltr">This discussion reminds me of an example I ran into
a couple weeks ago, where the execution of the program is
dependent precisely upon whether the ABI calls for the object to
be passed indirectly, or in a register
<div><br>
</div>
<div>In the case where NVRO is triggered, the class member foo_
is fully-constructed on the first line of CreateFoo (despite
appearing as if that's only constructing a local variable). In
the case where the struct is small enough to fit in a
register, NVRO does not apply, and in that case, foo_ isn't
constructed until after CreateFoo returns.
<div>
<div><br>
</div>
<div>Therefore, I believe it's implementation-defined
whether the following program has undefined behavior.<br>
</div>
<div><br>
</div>
<div>
<div>
<div><a href="https://godbolt.org/z/YT9zsz" moz-do-not-send="true">https://godbolt.org/z/YT9zsz</a><br>
</div>
<div><br>
</div>
<div><font face="monospace">#include <assert.h><br>
<br>
struct Foo {<br>
int x;<br>
<b> // assert fails if you comment out these
unused fields!<br>
</b> int dummy[4];<br>
};<br>
<br>
struct Bar {<br>
Bar() : foo_(CreateFoo()) {}<br>
<br>
Foo CreateFoo() {<br>
Foo f;<br>
f.x = 55;<br>
assert(foo_.x == 55);<br>
return f;<br>
}<br>
Foo foo_;<br>
};<br>
<br>
int main() {<br>
Bar b;<br>
}</font><br>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<p><br>
</p>
<p>Looks that way to me too. The example in 11.10.5p2 sort of makes
this point as well (by pointing out that you can directly
initialize a global this way).</p>
<p> -Hal</p>
<p><br>
</p>
<blockquote type="cite" cite="mid:CAA2zVHrPOXHYFK7NmGRd1o8V_=7AZVA=et4AipTOHY5dpwbENA@mail.gmail.com"><br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Fri, Jul 31, 2020 at 2:27
PM Hal Finkel via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" moz-do-not-send="true">cfe-dev@lists.llvm.org</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<p><br>
</p>
<div>On 7/31/20 1:24 PM, Hal Finkel wrote:<br>
</div>
<blockquote type="cite">
<div>On 7/31/20 12:43 PM, John McCall wrote:<br>
</div>
<blockquote type="cite">
<div style="font-family:sans-serif">
<div style="white-space:normal">
<p dir="auto">n 31 Jul 2020, at 7:35, Hal Finkel
wrote:</p>
</div>
<div style="white-space:normal">
<blockquote style="border-left:2px solid
rgb(119,119,119);color:rgb(119,119,119);margin:0px
0px 5px;padding-left:5px">
<p dir="auto">On 7/29/20 9:00 PM, John McCall via
cfe-dev wrote:</p>
<blockquote style="border-left:2px solid
rgb(153,153,153);color:rgb(153,153,153);margin:0px
0px 5px;padding-left:5px">
<p dir="auto">On 29 Jul 2020, at 17:42, Richard
Smith wrote:<br>
<br>
On Wed, 29 Jul 2020 at 12:52, John McCall <a href="mailto:rjmccall@apple.com" target="_blank" moz-do-not-send="true"><rjmccall@apple.com></a>
wrote:<br>
<br>
...<br>
<br>
I think concretely, the escape hatch doesn't
stop things from<br>
going wrong,<br>
because -- as you note -- even though we
*could* have made a copy,<br>
it's<br>
observable whether or not we *did* make a
copy. For example:<br>
<br>
I would say that it’s observable whether the
parameter variable has<br>
the same address as the argument. That doesn’t
/have/ to be the same<br>
question as whether a copy was performed: we
could consider there to be<br>
a formal copy (or series of copies) that
ultimately creates /an/ object<br>
at the same address, but it’s not the /same/
object and so pointers<br>
to the old object no longer validly pointer to
it. But I guess that<br>
would probably violate the lifetime rules,
because it would make accesses<br>
through old pointers UB when in fact they
should at worst access a valid<br>
object that’s just unrelated to the parameter
object.<br>
</p>
</blockquote>
<p dir="auto">I think that it would be great to be
able to do this, but unfortunately, I think that
the point that you raise here is a key issue.
Whether or not the copy is performed is visible
in the model, and so we can't simply act as
though there was a copy when optimizing. Someone
could easily have code that looks like:<br>
<br>
Foo DefaultX;<br>
<br>
...<br>
<br>
void something(Foo &A, Foo &B) {<br>
<br>
if (&A == &B) { ... }<br>
<br>
}<br>
<br>
void bar(Foo X) { something(X, DefaultX); }</p>
</blockquote>
</div>
<div style="white-space:normal">
<p dir="auto">This example isn’t really on point; a
call like <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7">bar(DefaultX)</code>
obviously cannot just pass the address of <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7">DefaultX</code> as a
by-value argument without first proving a lot of
stuff about how <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7">foo</code> uses both
its parameter and <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7">DefaultX</code>. I
think <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7">noalias</code> is
actually a subset of what would have to be proven
there.</p>
</div>
</div>
</blockquote>
<p><br>
</p>
<p>Yes, I apologize. You're right: my pseudo-code missed
the point. So the record is clear, let me rephrase:</p>
Foo *DefaultX = nullptr;<br>
...<br>
Foo::Foo() { if (!DefaultX) DefaultX = this; }<br>
...<br>
void bar(Foo X) { something(X, *DefaultX); }<br>
...<br>
bar(Foo{});
<p>I think that's closer to what we're talking about.<br>
</p>
<p><br>
</p>
<blockquote type="cite">
<div style="font-family:sans-serif">
<div style="white-space:normal">
<p dir="auto">In general, the standard is clear that
you cannot rely on escaping a pointer to/into a
trivially-copyable pr-value argument prior to the
call and then rely on that pointer pointing into
the corresponding parameter object.
Implementations are <em>allowed</em> to introduce
copies. But it does seem like the current wording
would allow you to rely on that pointer pointing
into <em>some</em> valid object, at least until
the end of the caller’s full-expression. That
means that, if we don’t guarantee to do an actual
copy of the argument, we cannot make it UB to
access the parameter variable through pointers to
the argument temporary, which is what marking the
parameter as <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7">noalias</code> would
do.</p>
<p dir="auto">So I guess the remaining questions
are:</p>
<ul>
<li>Is this something we can reasonably change in
the standard?</li>
</ul>
</div>
</div>
</blockquote>
<p><br>
</p>
<p>This is the part that I'm unclear about. What change
would we make? <br>
</p>
<p><br>
</p>
</blockquote>
<p><br>
</p>
<p>Also, maybe some extended use of the no_unique_address
attribute would help?<br>
</p>
<p> -Hal</p>
<p><br>
</p>
<blockquote type="cite">
<p> </p>
<p><br>
</p>
<blockquote type="cite">
<div style="font-family:sans-serif">
<div style="white-space:normal">
<ul>
<li>Are we comfortable setting <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7">noalias</code> in C
if the only place that would break is with a C++
caller?</li>
</ul>
</div>
</div>
</blockquote>
<p><br>
</p>
<p>Out of curiosity, if you take C in combination with our
statement-expression extension implementation (<a href="https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html" target="_blank" moz-do-not-send="true">https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html</a>),
and notwithstanding the statement in the GCC manual
about returns by value (i.e., the part just before where
it says, "Therefore the this pointer observed by Foo is
not the address of a."), is there any relationship to
this topic?</p>
<p>Thanks again,</p>
<p>Hal<br>
</p>
<p><br>
</p>
<blockquote type="cite">
<div style="font-family:sans-serif">
<div style="white-space:normal">
<ul>
</ul>
<p dir="auto">John.</p>
</div>
<div style="white-space:normal">
<blockquote style="border-left:2px solid
rgb(119,119,119);color:rgb(119,119,119);margin:0px
0px 5px;padding-left:5px">
<p dir="auto">As Richard's example shows, the code
doesn't need to explicitly compare the addresses
to detect the copy either. Any code that
reads/writes to the objects can do it. A
perhaps-more-realistic example might be:<br>
<br>
int Cnt = A.RefCnt; ++A.RefCnt; ++B.RefCnt; if
(Cnt + 1 != A.RefCnt) { /* same object case */ }<br>
<br>
The best suggestion that I have so far is that
we could add an attribute like 'can_copy'
indicating that the optimizer can make a formal
copy of the argument in the callee and use that
instead of the original pointer if that seems
useful. I can certainly imagine a transformation
such as LICM making use of such a thing
(although the cost modeling would probably need
to be fairly conservative).<br>
<br>
-Hal<br>
<br>
</p>
<blockquote style="border-left:2px solid
rgb(153,153,153);color:rgb(153,153,153);margin:0px
0px 5px;padding-left:5px">
<p dir="auto">...<br>
<br>
John.<br>
<br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" moz-do-not-send="true">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" style="color:rgb(153,153,153)" target="_blank" moz-do-not-send="true">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a></p>
</blockquote>
<p dir="auto">-- <br>
Hal Finkel<br>
Lead, Compiler Technology and Programming
Languages<br>
Leadership Computing Facility<br>
Argonne National Laboratory</p>
</blockquote>
</div>
<div style="white-space:normal"> </div>
</div>
</blockquote>
<pre cols="72">--
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
</blockquote>
<pre cols="72">--
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
</div>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" moz-do-not-send="true">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank" moz-do-not-send="true">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote>
</div>
</blockquote>
<pre class="moz-signature" cols="72">--
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
</body>
</html>