[Issue 24225] New: @safe cast from base type to enum bypasses copy ctor, identity opAssign
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Fri Nov 3 23:25:36 UTC 2023
https://issues.dlang.org/show_bug.cgi?id=24225
Issue ID: 24225
Summary: @safe cast from base type to enum bypasses copy ctor,
identity opAssign
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: normal
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: snarwin+bugzilla at gmail.com
Enum types in D always have trivial copy and assignment operations, regardless
of their base type. Normally this is ok, because enum members are required to
be compile-time constants, and cannot own any resources that require lifetime
management at runtime.
However, this means that casting a value from the base type to the enum type
allows any user-defined copy constructors and assignment operators (including
@disabled ones) to be completely bypassed.
Currently, this is allowed in @safe code, as the example program below
demonstrates:
---
import std.stdio;
struct UniqueInt
{
@system int n;
this(int n) @safe
{
writefln("Construct UniqueInt(%d)", n);
this.n = n;
}
@disable this(ref inout UniqueInt) inout;
~this() @trusted
{
writefln("Destroy UniqueInt(%d)", this.n);
this.n = 0;
}
}
enum E : UniqueInt { _ = UniqueInt.init }
void main() @safe
{
import core.lifetime;
UniqueInt n = 12345;
E en = cast(E) n;
UniqueInt n2 = move(en);
}
---
When compiled (with -preview=systemVariables) and run, it produces the
following output:
---
Construct UniqueInt(12345)
Destroy UniqueInt(12345)
Destroy UniqueInt(12345)
Destroy UniqueInt(12345)
---
The same UniqueInt is destroyed 3 times, even though only one instance is ever
constructed.
To prevent @safe code from bypassing user-defined assignment and copy
operations, which may be relied on to maintain an object's safety invariants,
casting from an enum's base type to the enum type should be made @system.
--
More information about the Digitalmars-d-bugs
mailing list