Issue 12885 - const union wrongly converts implicitly to mutable
Summary: const union wrongly converts implicitly to mutable
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 major
Assignee: No Owner
URL:
Keywords: accepts-invalid, pull, safe
Depends on: 12883
Blocks:
  Show dependency treegraph
 
Reported: 2014-06-09 23:36 UTC by Nils
Modified: 2024-06-20 10:04 UTC (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Nils 2014-06-09 23:36:01 UTC
---
union U
{
    int i;
    int* p;
}
void main()
{
    const U c;
    U m = c;
}
---

This has been enabled by the fix to issue 11257. I think this behaviour is not acceptable. The change has been made to "allow const(Rebindable) to Rebindable conversion". I think this should be implemented in Rebindable itself, as that's the place where we can give the guarantee not to alter the wrapped const/immutable data. alias this can be used for this once issue 12883 is fixed.
Comment 1 Nils 2014-06-24 19:14:03 UTC
As issue 12883 has been closed as invalid, I don't have a plan how to go about this. Unassigning from me.
Comment 2 FeepingCreature 2018-09-21 09:04:47 UTC
I just ran into this. This bug breaks std.json quite badly: see https://issues.dlang.org/show_bug.cgi?id=19256 , in which const(JSONValue) implicitly converts to JSONValue, allowing us to mutate JSON objects via a const parameter.

This is definitely unacceptable.
Comment 3 Martin Nowak 2018-11-01 11:38:48 UTC
I don't fully agree with the reasoning in issue 11257.
It seems like casts could be used to bypass const checks for implementations of Rebindable et.al.
Comment 4 Walter Bright 2018-12-16 09:55:39 UTC
Martin is right.
Comment 5 Walter Bright 2018-12-16 09:58:39 UTC
https://github.com/dlang/dmd/pull/9061
Comment 6 Steven Schveighoffer 2022-05-15 01:51:27 UTC
I just ran into this, with vibe.d Json type. Well, not a problem exactly, I just noticed I happened to be stripping const by accident, and it alarmed me that the compiler lets you get away with it.

I will note that this fails:

```d
union U
{
   int *p;
   int i;
}
void main()
{
   const U c;
   U m = c;
}
```

I see no reason why this should fail but the other should not, the inconsistency itself is a problem.

But beyond that, I will note that a struct that contains such an overlapping is convertible from const to mutable in @safe code. This in itself isn't a problem since you can't access the pointer value in @safe code. But surely if you wanted to provide access for @safe callers (like, for a tagged union, like Json), there would be trusted escapes, and those would surely not expect an implicit conversion of a const pointer to a mutable pointer.
Comment 7 Ate Eskola 2022-05-19 07:35:16 UTC
As a hole in the type system that allows undefined behaviour in @safe code, I think this needs higher severity. Increasing to major.
Comment 8 Steven Schveighoffer 2022-05-19 14:27:32 UTC
Also added safe tag.
Comment 9 Dlang Bot 2024-06-17 20:11:50 UTC
@ntrel created dlang/dmd pull request #16594 "Fix Bugzilla 12885 - const union wrongly converts implicitly to mutable" fixing this issue:

- Fix Bugzilla 12885 - const union wrongly converts implicitly to mutable

https://github.com/dlang/dmd/pull/16594
Comment 10 Dlang Bot 2024-06-20 10:04:17 UTC
dlang/dmd pull request #16594 "Fix Bugzilla 12885 - const union wrongly converts implicitly to mutable" was merged into master:

- 7531b1ae708a478900984734aec044d4dd38379c by Nick Treleaven:
  Fix Bugzilla 12885 - const union wrongly converts implicitly to mutable

https://github.com/dlang/dmd/pull/16594