<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8">
</head>
<body>
<div style="font-family:sans-serif"><div style="white-space:normal">
<p dir="auto">Clang IRGen currently doesn’t mark indirect parameters as <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">noalias</code>.  Considerations:</p>

<ul>
<li><p dir="auto">A lot of targets don’t pass struct arguments indirectly outside of C++, but some do, notably AArch64.</p></li>
<li><p dir="auto">In a pure C world, we would always be able to mark such parameters <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">noalias</code>, because arguments are r-values and there’s no way to have a pointer to an r-value.</p></li>
<li><p dir="auto">ObjC <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">__weak</code> references can have pointers to them from the ObjC runtime.  You can’t pass a weak reference immediately as an argument because <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">__weak</code> is a qualifier and qualifiers are ignored in calls, but you can put one in a struct and pass that, and that struct has to be passed indirectly.  Arguably such a parameter cannot be <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">noalias</code> because of the pointer from the runtime, but then again, ObjC code isn’t allowed to directly access the weak reference (it has to call the runtime), which means that no accesses that LLVM can actually see violate the <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">noalias</code> restriction.</p></li>
<li><p dir="auto">C++ parameters of non-trivially-copyable class type cannot be marked <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">noalias</code>: it is absolutely permitted to escape a pointer to <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">this</code> within a constructor and to replace that pointer whenever the object is moved.  This is both well-defined and sometimes useful.</p></li>
<li><p dir="auto">It’s actually possible to escape a pointer to <em>any</em> C++ object within its constructor, and that pointer remains valid for the duration of the object’s lifetime.  And you can do this with NRVO, too, so you don’t even need to have a type with non-trivial constructors, as long as the object isn’t copied.  Note that this even messes up the C case, which is really unfortunate: arguably we need to pessimize C code because of the possibility it might interoperate with C++.</p></li>
<li><p dir="auto">But I think there’s an escape hatch here.  C++ has a rule which is intended to give implementation extra leeway with passing and returning trivial types, e.g. to pass them in registers.  This rule is C++ [class.temporary]p3, which says that implementations can create an extra temporary object to pass an object of type <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">X</code> as long as “each copy constructor, move constructor, and destructor of X is either trivial or deleted, and X has at least one non-deleted copy or move constructor”.  This object is created by (trivially) copy/move-initializing from the argument/return object.  Arguably we can consider any type that satisfies this condition to be <em>formally</em> copied into a new object as part of passing or returning it.  We don’t need to <em>actually</em> do the copy, I think, we just need to consider a copy to have been done in order to formally disrupt any existing pointers to the object.  (Although arguably you aren’t allowed to copy an object into a new object at the original object’s current address; it would be an unfortunate consequence of this wording if we had to either forgo optimization or do an unnecessary copy here.)</p></li>
</ul>

<p dir="auto">Thoughts?</p>

<p dir="auto">John.</p>
</div>
</div>
</body>
</html>