<div dir="ltr"><div dir="ltr">On Wed, 14 Apr 2021 at 12:13, Nathan Sidwell <<a href="mailto:nathan@acm.org">nathan@acm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 4/14/21 2:39 PM, Richard Smith via cfe-dev wrote:<br>
> On Wed, 14 Apr 2021 at 08:49, Nathan Sidwell via cfe-dev <br>
> <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>>> wrote:<br>
> <br>
>     P0388<br>
>     <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0388r4.html" rel="noreferrer" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0388r4.html</a><br>
>     <<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0388r4.html" rel="noreferrer" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0388r4.html</a>><br>
>     Makes conversions between bounded-array and unbounded-array look like<br>
>     qualification conversions.  This means you can use const-cast to add<br>
>     array bounds (and implicitly lose bounds)<br>
> <br>
> <br>
> I think we changed the const_cast rules to disallow that. Here:<br>
> <br>
> Modify 7.6.1.10 [expr.const.cast] ¶3:<br>
> <br>
> "For two similar types T1 and T2, a prvalue of type T1 may be explicitly <br>
> converted to the type T2 using a const_cast <ins>if, considering the <br>
> cv-decompositions ([conv.qual]) of both types, all Pi1 are the same as <br>
> Pi2</ins>."<br>
> <br>
> A change in array bound would result in the Pi's differing between T1 <br>
> and T2, so a const_cast can't do that.<br>
<br>
Ah, I'd misunderstood that change, /and/ paid too much attention to <br>
'modelled like a cv qualifier'.<br>
<br>
> Regardless of the above observation about const_cast, I think we do need <br>
> to think about the cast kind for array bound conversions, because <br>
> implicit conversions can now remove an array bound, and static_cast can <br>
> now add one. Seems like the choices are CK_NoOp, CK_BitCast, or <br>
> something new. I don't like using CK_BitCast for this, since that <br>
> usually implies something more violent is happening (and would cause <br>
> problems for constant evaluation, which generally allows pointer bitcasts).<br>
<br>
Agreed. (CK_LValueBitCast also looked applicable)<br>
<br>
> CK_NoOp is really a misnomer, and should probably be renamed to <br>
> something that indicates what it actually models: a change in <br>
> qualifiers. I think that changing array bounds is notionally  the same <br>
> kind of type change as changing type qualifiers or 'noexcept' on a <br>
> function type (even though in IR it will result in a type change until <br>
> the work to remove pointee types is completed), so my inclination would <br>
> be to call that a CK_NoOp too, unless we have a reason not to -- and <br>
> that's probably also easier because it means we don't need to work out <br>
> how to decompose an arbitrary qualification conversion into a change of <br>
> cv-qualifiers and a separate change of array bounds. I think it should <br>
> be relatively straightforward to get CodeGen to insert bitcasts for <br>
> CK_NoOp casts where necessary.<br>
<br>
The fly in that ointment is, IIUC, that the array bounds changes are <br>
visible in IR, but the cv qualifier and noexcept changes are not?  So we <br>
have to emit some type conversion IR to avoid mismatches there -- that <br>
is how I ran into this problem after all.  I will go poke some more. <br>
Perhaps the cast emission for CK_NoOp (line 4674 of CGExpr.cpp)<br>
     return EmitLValue(E->getSubExpr());<br>
needs to do more, sometimes.<br></blockquote><div><br></div><div>Yes, I think we should create an IR-level bitcast where necessary here. At least one path through IR generation already does (EmitPointerWithAlignment), but it looks like we mostly assume that CK_NoOp is, well, a no-op for IR generation. (There's ongoing work to replace the IR-level "pointer to T" type family with a single "pointer" type, which would remove the need for a bitcast, but I think that's probably still months or years from being complete and I wouldn't imagine we want to wait for that.)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> On the subject of constant evaluation, do we have clear rules on whether <br>
> things like this work:<br>
> <br>
> constexpr int a[3][4] = {};<br>
> constexpr int (*p)[] = a;<br>
> constexpr int (*q)[12] = static_cast<int (*)[12]>(p);<br>
> constexpr int r = (*q)[5];<br>
> <br>
> ? I think that's probably valid up until the final line, which we should <br>
> reject for out-of-bounds array indexing because q points to an array of <br>
> 4 ints. (Though it might be nicer if we could reject the incorrect array <br>
> bound in the static_cast.) I think that's the behavior we'll get by <br>
> modeling this as a CK_NoOp.<br>
> <br>
>     nathan<br>
> <br>
>     -- <br>
>     Nathan Sidwell<br>
>     _______________________________________________<br>
>     cfe-dev mailing list<br>
>     <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>><br>
>     <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
>     <<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>><br>
> <br>
> <br>
> _______________________________________________<br>
> cfe-dev mailing list<br>
> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
> <br>
<br>
<br>
-- <br>
Nathan Sidwell<br>
</blockquote></div></div>