Jump to page: 1 2 3
Thread overview
July 29
As discussed in this thread:

https://www.digitalmars.com/d/archives/digitalmars/D/D_not_considered_memory_safe_374866.html

There are significant problems with making D default to being @safe, with respect to transitioning existing code to it. The problems are large enough that I fear it will deter people from putting in the work to make the transition.

The problems are:

1. Programs with cycles in the flow graph. The cycles mean any function in that cycle cannot be made @safe until all the functions in the cycle are @safe. My experience with transitioning large programs is that transitioning must be done incrementally, function by function, testing for no breakage after each change. Trying to do it all at once does not work, and never will work.

2. The difficulties in making functions @safe are:

 a. C strings

 b. unions that lay pointers over other values

 c. calling other functions that are not @safe/@trusted

 d. few functions are marked @safe/@trusted/@system

 e. safety inference is not done for most functions for various reasons

 f. safety inference can be problematic for cycles in the function flow graph

3. I proposed marking the unmarked functions @trusted, which will enable @safe to be done on a function-by-function basis. Timon objects on the basis of this will be lying about the functions having a safe interface, and the programmer is unlikely to complete fixing all of those functions.

I don't have an easy solution for 2.a and 2.b. But the rest boil down to a safe function not being able to call a system function. How can we ameliorate this problem?

The following is based on an idea that was proposed in that thread.

Function safety is actually in 4 states:

1. unattributed
2. @safe
3. @trusted
4. @system

So I propose "safe by default" to mean, for unattributed functions:

1. do all safety checks *except* checking for calling unattributed functions.

2. calling @system functions in unattributed functions will be flagged

3. calling unattributed functions will not affect attribute inference

----
This will not make the code safe by default. But it will make code a lot safer by default, and will provide a transition path. Code passing this will be a lot easier to transition to full safety.
July 29
Walter Bright kirjoitti 29.7.2024 klo 19.40:
> So I propose "safe by default" to mean, for unattributed functions:
> 
> 1. do all safety checks *except* checking for calling unattributed functions.
> 
> 2. calling @system functions in unattributed functions will be flagged
> 
> 3. calling unattributed functions will not affect attribute inference
> 
> ----
> This will not make the code safe by default. But it will make code a lot safer by default, and will provide a transition path. Code passing this will be a lot easier to transition to full safety.

This will mean there will be two levels of safety: unattributed and `@safe`. The only way they differ from each other is that you can't call unattributed functions from `@safe`.

Is the idea that unattributed would mean "probably safe but needs deeper scrutiny", like how you're using `@trusted` in DMD? Like, occasional safewashing would be okay for unattributed functions, or leaving unsafe C functions unmarked, but not so much for `@safe` or `@trusted`?

That's an interesting idea actually. Maybe it's the way to go!

I'm slightly worried it might lock us to almost-but-not-quite safe future, when people don't finish their job and mark external functions as `@system` when needed. But not as worried as I'm about the possibility D will stay mostly `@system` if we don't do this.
July 29
To clarify, this will not change attribute inference.
July 30
On 30/07/2024 4:40 AM, Walter Bright wrote:
> So I propose "safe by default" to mean, for unattributed functions:
> 
>  1.
>     do all safety checks /except/ checking for calling unattributed
>     functions.
>  2.
>     calling @system functions in unattributed functions will be flagged
>  3.
>     calling unattributed functions will not affect attribute inference

After changing unattributed with ``@unkownsafety`` attribute, this reads like it is acting as ``@safe`` with no extra steps.

BUT I think I know why!

It is the same diagnostic level!

In ``ErrorSink``:

```d
void memorySafety(Module m, TRUST safetyLevel, const ref Loc loc, const(char)* format, ...);
```

It needs to be configurable.

``-msoff dmd.*``
``-mswarn dmd.*``
``-msinfo dmd.*``

By default it could be set to info or off.


Basically, if a function is marked as ``@system`` or ``@trusted`` you don't do the ``@safe`` analysis. Otherwise for messages you call this function and determines what level to print it as.
July 29

On Monday, 29 July 2024 at 16:40:52 UTC, Walter Bright wrote:

>

This will not make the code safe by default. But it will make code a lot safer by default, and will provide a transition path. Code passing this will be a lot easier to transition to full safety.

I don't know what problem this would solve. My understanding of those wanting safe by default is that it would not move the needle at all relative to what's already in the language.

Is there something wrong with

  1. Adding a symbol to denote that you want your code to compile even though you haven't verified that it's safe. You can use that during the transition.
  2. Adding a -safe switch that won't compile if anything in your program is marked with (1). Then people that want safe actually get safe.
July 30
https://gist.github.com/rikkimax/37cc5db5f381a9adc1dde6a9bbcad46d

# Safer By Default

| Field           | Value            |
|-----------------|-----------------------------------------------------------------|
| DIP:            | (number/id -- assigned by DIP Manager)            |
| Author:         | Richard (Rikki) Andrew Cattermole <firstname@lastname.co.nz>                        |
| Implementation: | (links to implementation PR if any)            |
| Status:         | Draft            |

## Abstract

This proposal makes D more easily ``@safe`` by changing the default safety level and introducing new diagnostic logging level.

## Contents
* [Rationale](#rationale)
* [Prior Work](#prior-work)
* [Description](#description)
* [Breaking Changes and Deprecations](#breaking-changes-and-deprecations)
* [Reference](#reference)
* [Copyright & License](#copyright--license)
* [Reviews](#reviews)

## Rationale

Memory safety is increasing becoming more important to the programming field. With a signicant adoption rate of the Rust language, and with it governmental organizations becoming less tolerant of failure for compile time verifiable things. Furthermore this provides a transition path towards safety without preventing those who do not wish to not.

## Prior Work

This has many a NewsGroup post about it. Along with a DIP to change the default.

TODO: link something

## Description

To increase the memory safety of D, ``@safe`` must be the default for all new code.

### Language

This is a two pronged approach, the first is to introduce a new safety level, this has until now been the default.

```diff
AtAttribute:
+	@ unknownsafety
```

The attribute ``@unknownsafety`` may not be marked on a function with a body. But may be put on a function pointer.

If a function or a function pointer has not been marked with a safety attribute, it is inferred to be ``@unknownsafety``.

An ``@unknownsafety`` function:
- Must not call an ``@system`` function.
- Can call other ``@unknownsafety`` functions.
- Will be checked against the ``@safe`` checks.

If a ``@unknownsafety`` function passes all ``@safe`` checks, then it will be upgraded to ``@safe``.

### Compiler

In the compiler, the second approach takes place.
A new command line switch is added, ``-ms``.
This memory safety switch, will allow setting the diagnostic log level and for which module(s) to apply it to for all memory safety check messages.

Example:
- ``-msoff dmd.*``
- ``-mswarn std.*``
- ``-msinfo *``

The default level is info.

All memory safety errors that currently work by ``@safe`` would be converted to this diagnostic level.

## Breaking Changes and Deprecations

In current D2 edition, the default level will need to be off to prevent code breakage.
Otherwise for newer editions it will be info.

## Reference
Optional links to reference material such as existing discussions, research papers
or any other supplementary materials.

## Copyright & License
Copyright (c) 2024 by the D Language Foundation

Licensed under [Creative Commons Zero 1.0](https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt)

## History
July 30
I've changed my mind on disallowing ``@unknownsafety`` on functions.

If we allow it, extend this DIP over to ``@nogc`` and ``pure`` we could get a limited form of contract invalidation for ``opApply``.

``nothrow`` of course is covered by needing to introduce the throws set for value type exceptions.

So I'm liking this direction.
July 30

On Monday, 29 July 2024 at 18:23:37 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

https://gist.github.com/rikkimax/37cc5db5f381a9adc1dde6a9bbcad46d

I’m really liking this idea, I think this is very close to something I’d be fine with. I do have one reservation though:

Even people who want all of their code to be @safe (which includes myself) often need to use C libraries. Even if you check whole libraries to mark functions as @trusted, there are libraries like OpenGL which require using __gshared function pointers.
Riki’s DIP appears to address this by (correct me if I’m wrong) making it so that these external C functions, when unmarked, can be called by unmarked D code. The issue is, unmarked code can be upgraded to @safe. I think this upgrade process should not happen if a function calls an unmarked function with no body. In fact, I suggest we make body-less functions @system by default.

July 30

P.S. @unknownsafety is SO long. Maybe it should be something like @inferred?

July 30

On Tuesday, 30 July 2024 at 05:16:40 UTC, IchorDev wrote:

>

P.S. @unknownsafety is SO long. Maybe it should be something like @inferred?

More bikeshedding: @safeDefault? @safeAssume? @safeDirect?

« First   ‹ Prev
1 2 3