<div dir="ltr"><div dir="ltr">On Wed, 14 Apr 2021 at 08:49, Nathan Sidwell via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.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">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>
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></blockquote><div><br></div><div>I think we changed the const_cast rules to disallow that. Here:</div><div><br></div><div>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 converted to the type T2 using a const_cast <ins>if, considering the cv-decompositions ([conv.qual]) of both types, all Pi1 are the same as Pi2</ins>."<br></div><div><br></div><div>A change in array bound would result in the Pi's differing between T1 and T2, so a const_cast can't do that. </div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
But, ConstCast has a cast-kind of CK_NoOp:<br>
AST/ExprCXX.h:<br>
   CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,<br>
                    TypeSourceInfo *writtenTy, SourceLocation l,<br>
                    SourceLocation RParenLoc, SourceRange AngleBrackets)<br>
       : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, 0,<br>
                          /*HasFPFeatures*/ false, writtenTy, l, RParenLoc,<br>
                          AngleBrackets) {}<br>
<br>
That will no longer be true -- adding or removing bounds changes the <br>
type more than CK_NoOp permits.  This results in code emission assert <br>
failure when things like [4 x i32]* meets [0 x i32]*.<br>
<br>
so, should such constcasts generate non-ConstCast AST?, or should the <br>
ConstCast node sometimes not be CK_NoOp?  The latter seems better to me, <br>
but perhaps there's a different opinion?<br></blockquote><div><br></div><div>Regardless of the above observation about const_cast, I think we do need to think about the cast kind for array bound conversions, because implicit conversions can now remove an array bound, and static_cast can now add one. Seems like the choices are CK_NoOp, CK_BitCast, or something new. I don't like using CK_BitCast for this, since that usually implies something more violent is happening (and would cause problems for constant evaluation, which generally allows pointer bitcasts).</div><div><br></div><div>CK_NoOp is really a misnomer, and should probably be renamed to something that indicates what it actually models: a change in qualifiers. I think that changing array bounds is notionally  the same kind of type change as changing type qualifiers or 'noexcept' on a function type (even though in IR it will result in a type change until the work to remove pointee types is completed), so my inclination would be to call that a CK_NoOp too, unless we have a reason not to -- and that's probably also easier because it means we don't need to work out how to decompose an arbitrary qualification conversion into a change of cv-qualifiers and a separate change of array bounds. I think it should be relatively straightforward to get CodeGen to insert bitcasts for CK_NoOp casts where necessary.</div><div><br></div><div>On the subject of constant evaluation, do we have clear rules on whether things like this work:</div><div><br></div><div>constexpr int a[3][4] = {};</div><div>constexpr int (*p)[] = a;</div><div>constexpr int (*q)[12] = static_cast<int (*)[12]>(p);</div><div>constexpr int r = (*q)[5];</div><div><br></div><div>? I think that's probably valid up until the final line, which we should reject for out-of-bounds array indexing because q points to an array of 4 ints. (Though it might be nicer if we could reject the incorrect array bound in the static_cast.) I think that's the behavior we'll get by modeling this as a CK_NoOp.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
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><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>
</blockquote></div></div>