[Issue 19916] union member access should be un- at safe

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu May 30 00:13:27 UTC 2019


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

--- Comment #5 from Simen Kjaeraas <simen.kjaras at gmail.com> ---
(In reply to Manu from comment #4)
> union U
> {
>   int x = 10;
>   float f = void;
>   NotAPointer np = void;
> }
> U u;
> 
> float r = 10.0 + u.f; // <- f is uninitialised, r is junk

This is not a memory safety issue.


> u.np.callMethod(); // <- np is not a pointer, but still uninitialised, certain
> crash
> 
> Any access to a union member may interact with uninitialised memory.
> Accessing uninitialised memory is a memory safety issue.

I think I found an example that qualifies:

module someothermodule;

struct NotAPointer {
    private size_t n;
    @disable this();
    @trusted this(int* p) {
        assert(p.isValid);
        n = cast(size_t)p;
    }
    @trusted void callMethod() {
        *cast(int*)n = 3;
    }
}

While NotAPointer's wanton casting looks suspicious, p.isValid ensures the
pointer will stay valid as long as NotAPointer exists. We could even have a
private constructor and force the use of a factory function to ensure no stupid
pointers are passed to the constructor. Also, the use of @disable this() and
the private member ensures @safe user code won't be able to set n to something
silly.

...except for unions and void initialization. Both of these wreak havoc with
the assumptions of NotAPointer.

So yeah, I concede - there are clear ways to cause memory safety issues by
simple union member access in @safe methods.

--


More information about the Digitalmars-d-bugs mailing list