<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <div class="moz-cite-prefix">On 7/31/20 12:43 PM, John McCall wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:15AA8332-E764-4691-9C6F-90B4D5328906@apple.com">
      
      <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 #777; color:#777;
            margin:0 0 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 #777; color:#999;
              margin:0 0 5px; padding-left:5px; border-left-color:#999">
              <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 class="moz-txt-link-rfc2396E" href="mailto:rjmccall@apple.com"><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:#F7F7F7; border-radius:3px;
              margin:0; padding:0 0.4em" bgcolor="#F7F7F7">bar(DefaultX)</code>
            obviously cannot just pass the address of <code style="background-color:#F7F7F7; border-radius:3px;
              margin:0; padding:0 0.4em" bgcolor="#F7F7F7">DefaultX</code>
            as a by-value argument without first proving a lot of stuff
            about how <code style="background-color:#F7F7F7;
              border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">foo</code> uses both its parameter and <code style="background-color:#F7F7F7; border-radius:3px;
              margin:0; padding:0 0.4em" bgcolor="#F7F7F7">DefaultX</code>.
            I think <code style="background-color:#F7F7F7;
              border-radius:3px; margin:0; padding:0 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" cite="mid:15AA8332-E764-4691-9C6F-90B4D5328906@apple.com">
      <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:#F7F7F7; border-radius:3px;
              margin:0; padding:0 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>
    <p><br>
    </p>
    <blockquote type="cite" cite="mid:15AA8332-E764-4691-9C6F-90B4D5328906@apple.com">
      <div style="font-family:sans-serif">
        <div style="white-space:normal">
          <ul>
            <li>Are we comfortable setting <code style="background-color:#F7F7F7; border-radius:3px;
                margin:0; padding:0 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 class="moz-txt-link-freetext" href="https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html">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" cite="mid:15AA8332-E764-4691-9C6F-90B4D5328906@apple.com">
      <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 #777; color:#777;
            margin:0 0 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 #777; color:#999;
              margin:0 0 5px; padding-left:5px; border-left-color:#999">
              <p dir="auto">...<br>
                <br>
                John.<br>
                <br>
                <br>
                _______________________________________________<br>
                cfe-dev mailing list<br>
                <a class="moz-txt-link-abbreviated" href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
                <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" style="color:#999" 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 class="moz-signature" cols="72">-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
  </body>
</html>