Bug 24098 – Safe variable can be initialized from `@system` static constructor.

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-08-22T14:44:15Z
Last change time
2024-12-13T19:30:30Z
Keywords
accepts-invalid, safe, spec
Assigned to
No Owner
Creator
timon.gehr
Moved to GitHub: dmd#20322 →

Comments

Comment #0 by timon.gehr — 2023-08-22T14:44:15Z
DMD 2.105.0: ```d int* x; @system static this(){ x=cast(int*)0xDEADBEEF; } void main()@safe{ import std.stdio; writeln(*x); } ``` From the language specification: --- When it is only called with safe values and safe aliasing, a function has a safe interface when: 1. it cannot exhibit undefined behavior, and 2. it cannot create unsafe values that are accessible from other parts of the program (e.g., via return values, global variables, or ref parameters), and 3. it cannot introduce unsafe aliasing that is accessible from other parts of the program. Functions that meet these requirements may be @safe or @trusted. Function that do not meet these requirements can only be @system. --- Clearly the main function does not meet requirement 2., yet is annotated `@safe` and compiles. Fixing this may require some thinking about language design. One option is to require `static this` to be `@trusted` instead of `@system` when it attempts to initialize a non-`@system` variable.
Comment #1 by timon.gehr — 2023-08-22T14:53:35Z
Actually, depending on how exactly you interpret "create unsafe values", I guess my `main` function may not violate requirement 2. However, I think this is still a problem for memory safety in D and worth addressing.
Comment #2 by timon.gehr — 2023-08-22T14:59:32Z
I think the program is still at odds with the language specification even if requirement 2 is not considered to be violated, because clearly it violates requirement 1 and the preconditions hold (the preconditions do not say anything about the state of global variables). I think this is a related but somewhat independent bug in the specification, because there could also be `@trusted` code that messes up the state of a non-`@system` global.
Comment #3 by nick — 2024-03-22T21:38:33Z
> depending on how exactly you interpret "create unsafe values", I guess my `main` function may not violate requirement 2 I think dereferencing doesn't create an unsafe value, the static ctor created an unsafe pointer, which in turn points to an unsafe value. > clearly it violates requirement 1 and the preconditions hold (the preconditions do not say anything about the state of global variables). Yes, I think the preconditions need to mention safe context: > When it is only called with safe values and safe aliasing
Comment #4 by dlang-bot — 2024-03-23T17:38:27Z
@ntrel created dlang/dlang.org pull request #3789 "[spec] Fix Safe interface definition" mentioning this issue: - [spec] Fix Safe interface definition 1. Mention context and globals for preconditions. Part of Bugzilla 24098 - Safe variable can be initialized from `@system` static constructor. 2. `@trusted` functions can create unsafe values/aliasing so long as they are not accessible from `@safe` code. https://github.com/dlang/dlang.org/pull/3789
Comment #5 by dlang-bot — 2024-03-30T10:24:29Z
dlang/dlang.org pull request #3789 "[spec/function] Fix Safe Interface definition" was merged into master: - e3fd3f0e5bebb9884e05a1bc9031176a682df365 by Nick Treleaven: [spec] Fix Safe interface definition 1. Mention context and globals for preconditions. Part of Bugzilla 24098 - Safe variable can be initialized from `@system` static constructor. 2. `@trusted` functions can create unsafe values/aliasing so long as they are not accessible from `@safe` code. https://github.com/dlang/dlang.org/pull/3789
Comment #6 by robert.schadek — 2024-12-13T19:30:30Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20322 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB