But of course, it's the right thing to do when you've got one type that can be aliased to anything through a pointer, and the other cannot.
Sure, if that's what were going on, but it's not. What we have are two *pointer types*, both pointing at the same underlying type. Access via one of those pointer types is assumed to be aliasing anything and the other is not. The case in Ada is type r1 is record ... end record; type ar1 is access all r1; type r2 is record ... end record; type ar2 is access all r2; type ar2p is access all r2; function uc is new unchecked_conversion (ar1, ar2p); In this case, both ar2.all and ar2p.all are accessing r2. But accesses through ar2p must be presumed to access anything since we know that the underlying object might be an ar1. > What's special here is the pointer type, not the underlying type. Which means that everywhere that handles pointer types and aliasing has to be modified to check this magic. At the RTL level, there's just one place that computes the alias set of an expression and it knows about that flag. It was the only place that had to be modified to support it, as I recall. One would hope that knowlege of this semantics can be similarly localized at the tree level. Why can't it?