February 08, 2019
On Friday, February 8, 2019 1:02:59 AM MST ag0aep6g via Digitalmars-d wrote:
> On 07.02.19 23:33, Luís Marques wrote:
> > You are discussing evaluating the safety to the variable. Why not evaluate the safety of the variable's initialization expression? That is, @safe would always refer to code, just not necessarily functions.
>
> Evaluating the safety of initializers without somehow marking the variables as @safe/@system would fix the issue you brought up, but not the one that Olivier is talking about.
>
> His point is that you would still have to check manually if the globals you're using are safe or not. The compiler wouldn't see a difference between a safely initialized global and an unsafely initialized one.
>
> But @safe is supposed to eliminate that kind of manual verification.
>
> ----
> @safe:
> int* x = /* ... this initializer would be checked for safety ... */;
> void main()
> {
>      *x = 7; /* Guaranteed to be safe. */
>      *y = 7; /* Might exhibit undefined behavior. */
> }
> @system:
> int* y = /* ... this initializer would not be checked ... */;
> ----
>
> If we'd apply the attributes to the variables, and forbid using @system variables in @safe code, then `*y = 7;` would be rejected.

Except that there's no such thing as an @safe or @system variable. You're talking about the exact same problem as when you have an @safe function which takes a pointer, and you give it a pointer to invalid memory. @safety depends on you giving valid input to @safe functions. So, if you have an @safe function using a module-level variable whose initializer isn't @safe, and it does something which makes that module-level variable unsafe to use, then you're giving the function invalid input, just like if you passed it an invalid pointer via one of its explicit parameters.

- Jonathan M Davis




February 08, 2019
On 08.02.19 09:31, Jonathan M Davis wrote:
> Except that there's no such thing as an @safe or @system variable.

Of course there isn't now. The idea is to add that concept to the language.

> You're
> talking about the exact same problem as when you have an @safe function
> which takes a pointer, and you give it a pointer to invalid memory.

In that scenario, you're making the invalid call from @system/@trusted code. There you're supposed to watch out for this kind of stuff.

You might argue that globals are located in an @system context, so it's okay when they compromise otherwise @safe functions. Then one just has to take care when declaring globals, since they're inputs to all @safe functions. I guess that's a reasonable position, but I don't think it's the most useful one.

Right now, to ensure that a program is actually safe, one has to:

1) Check `main`. I.e., mark it @safe, or verify it manually.
2) Manually verify all @trusted code.
3) Check all static constructors.
4) Check all statically initialized variables that are not in a function: module-level variables, class/struct fields, anything else?
5) Account for bugs in @safe and stuff that I'm forgetting here.

Ideally, the list would be as short as possible. So if we can eliminate #4, that would be a good thing, in my opinion.
February 08, 2019
On Thursday, 7 February 2019 at 22:33:45 UTC, Luís Marques wrote:
> On Thursday, 7 February 2019 at 17:33:01 UTC, Olivier FAURE wrote:
>> One way to fix this would be to forbid using @system global variables in @safe functions, but this would definitely be a breaking change, unless global variable safety is determined by the compiler by default (which is its own can of worms).
>
> You are discussing evaluating the safety to the variable. Why not evaluate the safety of the variable's initialization expression? That is, @safe would always refer to code, just not necessarily functions.

Yes, that's what I meant by "variable safety". In retrospect, that was a little ambiguous.
February 08, 2019
On Friday, 8 February 2019 at 09:40:09 UTC, ag0aep6g wrote:
> Right now, to ensure that a program is actually safe, one has to:
>
> 1) Check `main`. I.e., mark it @safe, or verify it manually.
> 2) Manually verify all @trusted code.
> 3) Check all static constructors.
> 4) Check all statically initialized variables that are not in a function: module-level variables, class/struct fields, anything else?
> 5) Account for bugs in @safe and stuff that I'm forgetting here.
>
> Ideally, the list would be as short as possible. So if we can eliminate #4, that would be a good thing, in my opinion.

Right.

Like I said earlier, one way to eliminate #4 would be to say "variables that aren't marked as @safe can't be called from safe code". The problem with that is that it would break tons of existing code.

Alternate solutions:
- Make global variables @safe by default.
- Deduce @safety by default from a global variable's initialization expression.

Both of these solutions would involve very little code breakage, but would break with existing D semantics, which is yet another wart you have to explain to beginners.

(alternate alternate solution: make an "everything is @safe by default" DIP, and use a -dipXXXX flag for the transition for a few years)
February 12, 2019
On Friday, 8 February 2019 at 20:06:02 UTC, Olivier FAURE wrote:
>
> (alternate alternate solution: make an "everything is @safe by default" DIP, and use a -dipXXXX flag for the transition for a few years)

I don't think this would be well received by the betterC/C++ crowd. And as important as @safe is for some applications, the decision to make it optional and not default was taken long ago, and has huge implications. Fixing backwards compatibility for this related but separate issue is hardly a warrant for such a huge change.

It looks to me too that variables need now to be flagged with the attribute, because the alternative is for every one of the @safe functions that use any given global variable, to check again on their own that there isn’t anything unsafe in its initialization code. And then again, you are pushing the compile error that belongs on the dependency (global initialization) to the client (@safe function)

A possible solution in my opinion is:

- From then on, globals will be flagged @safe, @system or @trusted just like functions.

- But under the hood, globals in binaries (already compiled,  so currently always without any attribute) are accepted by @safe code (as if they were @trusted) – BUT generate a compile warning.

- When compiling new code, globals in this code are subject to new restrictions; so they are flagged @safe, @trusted or @system explicitly; and if their initialization is unsafe and they’re flagged as @safe, they generate a compile error; without need for any other compilation unit that uses this variable to check on its own.

This way there is no code break. Other than new warnings, which are good because they expose a newly discovered vulnerability; or re-compiling unsafe global initializations, which should be fixed, or may be flagged @trusted, individually or however.
February 12, 2019
On Tuesday, 12 February 2019 at 12:49:45 UTC, XavierAP wrote:
>
> - When compiling new code, globals in this code are subject to new restrictions; so they are flagged @safe, @trusted or @system explicitly;

Sorry instead of "explicitly" I should have said according to the same rules as functions. So if they're not found in a @safe or @trusted region, they will be flagged as @system.

The difference is that globals from binaries would be specially considered as "@trusted with warning" until re-compiled (regardless of what region they were compiled from originally, which cannot likely be known).
February 12, 2019
On Tuesday, 12 February 2019 at 12:49:45 UTC, XavierAP wrote:
> This way there is no code break. Other than new warnings, which are good because they expose a newly discovered vulnerability; or re-compiling unsafe global initializations, which should be fixed, or may be flagged @trusted, individually or however.

There would be some breakage for code with "@safe:" at the beginning of the file.

Also, I don't think D compilers have any semantics for behaving differently depending on whether the code they're compiling is legacy or new code (eg already compiled code, as you put it). I'm guessing that those semantics would be non-trivial to implement.
February 13, 2019
On Tuesday, 12 February 2019 at 23:17:56 UTC, Olivier FAURE wrote:
>
> There would be some breakage for code with "@safe:" at the beginning of the file.

Only if the file contained unsafe code in initializations. And if we consider this a bug rather than an enhancement, the code would have been already broken. The compiler should break that code; and it should have always detected it and generated an error.

I wouldn't think there are lots of such unsafe code hidden in global initializations within @safe files, in Phobos or elsewhere. And wherever there is, it should be broken.

But you could always fix it by only adding @trusted.

> Also, I don't think D compilers have any semantics for behaving differently depending on whether the code they're compiling is legacy or new code (eg already compiled code, as you put it). I'm guessing that those semantics would be non-trivial to implement.

I wouldn't add any new semantics or mechanism. If the code is being compiled, @safe should be enforced. I was talking about the situation where you link to binary libraries (compiled with an old version with this bug).

Whenever (very often) dependencies are compiled from source instead, the new errors should simply pop up and break the compilation. This also means that at the same time this is fixed in the compiler, any such unsafe code in Phobos should be fixed.
February 13, 2019
On Wednesday, 13 February 2019 at 00:25:27 UTC, XavierAP wrote:
> I wouldn't add any new semantics or mechanism. If the code is being compiled, @safe should be enforced. I was talking about the situation where you link to binary libraries (compiled with an old version with this bug).
>
> Whenever (very often) dependencies are compiled from source instead, the new errors should simply pop up and break the compilation. This also means that at the same time this is fixed in the compiler, any such unsafe code in Phobos should be fixed.

Yup, Phobos always gets compiled with `-de` on _every_ PR to DMD, s.t. every fix/improvement to the compiler needs to fix Phobos (and druntime first).

Also, the ~ top50 Dub project are tested as well (https://buildkite.com/dlang), so that's why (hard) breaking changes aren't going to happen these days.
Here's a recent example:

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

Though of course there have been exceptions where @safe-ty fixes affected only one of those 50 Dub packages and have been deemed as critical (+ affecting only a small subset + easy to fix), so that simply that one package was fixed.
1 2 3
Next ›   Last »