[Issue 21565] @safe code allows modification of a scalar that overlaps with a pointer

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Jan 21 17:12:51 UTC 2021


https://issues.dlang.org/show_bug.cgi?id=21565

--- Comment #8 from Steven Schveighoffer <schveiguy at gmail.com> ---
(In reply to RazvanN from comment #5)
> (In reply to Steven Schveighoffer from comment #3)
> > If you do intend to access the int *, then having any safe code anywhere
> > just change the integer ruins the any safety assumptions that the @trusted
> > or @system code can make. Essentially, it means @trusted code can never
> > access such a union reliably except to access just the integer.
> 
> Trusted does not offer any guarantees.

This is why I said "assumptions" and not "guarantees". It's in fact impossible
for a trusted function to guarantee the union state between calls, because safe
code can do anything it wants with the union so long as there is a mutable
basic type involved.

> You can do whatever you want there.
> If you want to access a pointer that is overlapped with an integer that is
> the users' problem not the typesystems'. You cannot assume anything with
> regards to that pointer, that is the reason why it is not allowed in @safe
> code. In case you do use and you have a segfault, then the developer will
> have
> to audit the trusted blocks, not the @safe ones.

Auditing is not possible. The trusted code cannot make any assumptions about
the union, it must ALWAYS treat it as an integer (at least when it comes in).
Inside the function, sure, it can assign things. But as soon as it leaves the
function, it must be treated as an integer again. This means, such unions serve
no purpose as parameters to trusted code. Ever.

In which case, using such a union in safe code is pointless. It's more
productive to follow the rules already set in the spec.

> I think that this is an issue were reasonable people may disagree, but the
> fact is that @safe is checked with regards to operations not data
> structures. There is no concept of @safe union or @system union in D. It is
> the way you use it that makes it @safe/@system. From this point of view,
> setting an integer that is overlapped with a pointer is not unsafe, however
> accessing a pointer that is overlapped with an integer is.

This is a misunderstanding. @safe has everything to do with data structures,
and the semantics surrounding those data structures. If we don't have data
rules for @safe code, then @trusted code cannot make any reasonable assumptions
about the incoming parameters. Remember that @trusted code MUST ASSUME it is
being called from @safe code.

For example, @safe ascribes a semantic meaning to the length field of an array.
It means "all the items that are pointed to by the pointer that are up to that
length are accessible." Without that, arrays of data could not be passed to a
@trusted function.

We also have rules for an incoming pointer, which means, it only can point at a
single valid value, or null. Using these rules, one can write useful @trusted
code. Without such rules, either trusted code would have to assume any incoming
parameters are suspect, or we have to review all code including @safe code.

With a rule of "Incoming union values can only ever have scalar values set" is
unnecessarily limiting. If you can only set the scalar values, why have a union
that is usable in safe code that has pointer and scalar values mixed?

It's what makes the DIP1035 proposal so promising -- you can ascribe your own
semantic rules to types that the compiler doesn't have built in.

--


More information about the Digitalmars-d-bugs mailing list