Skip to content

Commit 6557de2

Browse files
authored
Merge pull request #2773 from aG0aep6G/safe-values
safe interfaces, safe values, safe aliasing merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
2 parents 43d0e38 + b07d3d5 commit 6557de2

File tree

1 file changed

+242
-13
lines changed

1 file changed

+242
-13
lines changed

spec/function.dd

Lines changed: 242 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2836,17 +2836,14 @@ $(H2 $(LNAME2 nogc-functions, No-GC Functions))
28362836

28372837
$(H2 $(LNAME2 function-safety, Function Safety))
28382838

2839-
$(P $(I Safe functions) are functions that are statically checked
2840-
to exhibit no possibility of
2841-
$(DDSUBLINK glossary, undefined_behavior, $(I undefined behavior)).
2842-
Undefined behavior is often used as a vector for malicious
2843-
attacks.
2844-
)
2845-
28462839
$(H3 $(LNAME2 safe-functions, Safe Functions))
28472840

28482841
$(P Safe functions are marked with the $(CODE @safe) attribute.)
28492842

2843+
$(P Safe functions have $(RELATIVE_LINK2 safe-interfaces, safe
2844+
interfaces). An implementation must enforce this by restricting the
2845+
function's body to operations that are known safe.)
2846+
28502847
$(P The following operations are not allowed in safe
28512848
functions:)
28522849

@@ -2884,16 +2881,27 @@ $(H3 $(LNAME2 safe-functions, Safe Functions))
28842881
so they can be corrected.
28852882
)
28862883

2884+
$(H4 Safe External Functions)
2885+
2886+
$(P External functions don't have a function body visible to the compiler:
2887+
)
2888+
---
2889+
@safe extern (C) void play();
2890+
---
2891+
and so safety cannot be verified automatically.
2892+
2893+
$(BEST_PRACTICE Explicitly set an attribute for external functions rather
2894+
than relying on default settings.)
2895+
28872896
$(H3 $(LNAME2 trusted-functions, Trusted Functions))
28882897

28892898
$(P Trusted functions are marked with the $(CODE @trusted) attribute.)
28902899

2891-
$(P Trusted functions are guaranteed to not exhibit any undefined
2892-
behavior if called by a safe function. Furthermore, calls to trusted
2893-
functions cannot lead to undefined behavior in `@safe` code that is
2894-
executed afterwards. It is the responsibility of the programmer to
2895-
ensure that these guarantees are upheld.
2896-
)
2900+
$(P Like $(RELATIVE_LINK2 safe-functions, safe functions), trusted
2901+
functions have $(RELATIVE_LINK2 safe-interfaces, safe interfaces).
2902+
Unlike safe functions, this is not enforced by restrictions on the
2903+
function body. Instead, it is the responsibility of the programmer to
2904+
ensure that the interface of a trusted function is safe.)
28972905

28982906
$(P Example:)
28992907

@@ -2952,6 +2960,227 @@ $(H3 $(LNAME2 system-functions, System Functions))
29522960
$(P System functions are $(B not) covariant with trusted or safe functions.
29532961
)
29542962

2963+
$(BEST_PRACTICE When in doubt, mark `extern (C)` and `extern (C++)` functions as
2964+
`@system` when their implementations are not in D, as the D compiler will be
2965+
unable to check them. Most of them are `@safe`, but will need to be manually
2966+
checked.)
2967+
2968+
$(H3 $(LNAME2 safe-interfaces, Safe Interfaces))
2969+
2970+
$(P Given that it is only called with $(RELATIVE_LINK2 safe-values, safe
2971+
values) and $(RELATIVE_LINK2 safe-aliasing, safe aliasing), a
2972+
function has a safe interface when:)
2973+
$(OL
2974+
$(LI it cannot possibly exhibit
2975+
$(DDSUBLINK glossary, undefined_behavior, undefined behavior),
2976+
and)
2977+
$(LI it cannot create unsafe values that are accessible from other
2978+
parts of the program (e.g., via return values, global variables,
2979+
or `ref` parameters), and)
2980+
$(LI it cannot introduce unsafe aliasing that is accessible from
2981+
other parts of the program.)
2982+
)
2983+
2984+
$(P Functions that meet these requirements may be
2985+
$(RELATIVE_LINK2 safe-functions, `@safe`) or
2986+
$(RELATIVE_LINK2 trusted-functions, `@trusted`). Function that do not
2987+
meet these requirements can only be
2988+
$(RELATIVE_LINK2 system-functions, `@system`).)
2989+
2990+
$(P Examples:)
2991+
2992+
$(UL
2993+
$(LI
2994+
C's `free` does not have a safe interface:
2995+
---
2996+
extern (C) @system void free(void* ptr);
2997+
---
2998+
because `free(p)` invalidates `p`, making its value unsafe.
2999+
`free` can only be `@system`.
3000+
)
3001+
$(LI
3002+
C's `strlen` and `memcpy` do not have safe interfaces:
3003+
---
3004+
extern (C) @system size_t strlen(char* s);
3005+
extern (C) @system void* memcpy(void* dst, void* src, size_t nbytes);
3006+
---
3007+
because they iterate pointers based on unverified assumptions
3008+
(`strlen` assumes that `s` is zero-terminated; `memcpy` assumes
3009+
that `dst` and `src` are at least `nbytes` long). Any function
3010+
that traverses a C string passed as an argument can only be
3011+
`@system`. Any function that trusts a seperate parameter for
3012+
array bounds can only be `@system`.
3013+
)
3014+
$(LI
3015+
C's `malloc` does have a safe interface:
3016+
---
3017+
extern (C) @trusted void* malloc(size_t sz);
3018+
---
3019+
It does not exhibit undefined behavior for any input. It returns
3020+
either a valid pointer, which is safe, or `null` which is also
3021+
safe. It returns a pointer to a fresh allocation, so it cannot
3022+
introduce any unsafe aliasing.
3023+
)
3024+
$(LI
3025+
A D version of `memcpy` can have a safe interface:
3026+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
3027+
---
3028+
@safe void memcpy(E)(E[] src, E[] dst)
3029+
{
3030+
import std.math : min;
3031+
foreach (i; 0 .. min(src.length, dst.length))
3032+
{
3033+
dst[i] = src[i];
3034+
}
3035+
}
3036+
---
3037+
)
3038+
because the rules for safe $(RELATIVE_LINK2 safe-values, safe
3039+
values) ensure that the lengths of the arrays are correct.
3040+
)
3041+
)
3042+
3043+
$(H3 $(LNAME2 safe-values, Safe Values))
3044+
3045+
$(P For $(DDSUBLINK spec/type, basic-data-types, basic data types), all
3046+
possible bit patterns are safe.)
3047+
3048+
$(P A pointer is safe when:)
3049+
$(OL
3050+
$(LI it can be dereferenced validly, and)
3051+
$(LI the value of the pointee is safe.)
3052+
)
3053+
$(P Examples:)
3054+
$(SPEC_RUNNABLE_EXAMPLE_RUN
3055+
---
3056+
int* n = null; /* n is safe because dereferencing null is a well-defined
3057+
crash. */
3058+
int* x = cast(int*) 0xDEADBEEF; /* x is (most likely) unsafe because it
3059+
is not a valid pointer and cannot be dereferenced. */
3060+
3061+
import core.stdc.stdlib: malloc, free;
3062+
int* p1 = cast(int*) malloc(int.sizeof); /* p1 is safe because the
3063+
pointer is valid and *p1 is safe regardless of its actual value. */
3064+
free(p1); /* This makes p1 unsafe. */
3065+
int** p2 = &p1; /* While it can be dereferenced, p2 is unsafe because p1
3066+
is unsafe. */
3067+
p1 = null; /* This makes p1 and p2 safe. */
3068+
---
3069+
)
3070+
3071+
$(P A dynamic array is safe when:)
3072+
$(OL
3073+
$(LI its pointer is safe, and)
3074+
$(LI its length is in-bounds with the corresponding memory object,
3075+
and)
3076+
$(LI all its elements are safe.)
3077+
)
3078+
3079+
$(P Examples:)
3080+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
3081+
---
3082+
int[] f() @system
3083+
{
3084+
int[3] a;
3085+
int[] d1 = a[0 .. 2]; /* d1 is safe. */
3086+
int[] d2 = a.ptr[0 .. 3]; /* d2 is unsafe because it goes beyond a's
3087+
bounds. */
3088+
int*[] d3 = [cast(int*) 0xDEADBEEF]; /* d3 is unsafe because the
3089+
element is unsafe. */
3090+
return d1; /* Up to here, d1 was safe, but its pointer becomes
3091+
invalid when the function returns, so the returned dynamic array
3092+
is unsafe. */
3093+
}
3094+
---
3095+
)
3096+
3097+
$(P A static array is safe when all its elements are safe. Regardless
3098+
of the element type, a static array with length zero is always safe.)
3099+
3100+
$(P An associative array is safe when all its keys and elements are
3101+
safe.)
3102+
3103+
$(P A struct/union instance is safe when:)
3104+
$(OL
3105+
$(LI the values of its accessible fields are safe, and)
3106+
$(LI it does not introduce $(RELATIVE_LINK2 safe-aliasing, unsafe
3107+
aliasing) with unions.)
3108+
)
3109+
3110+
$(P Examples:)
3111+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
3112+
---
3113+
struct S { int* p; }
3114+
S s1 = S(new int); /* s1 is safe. */
3115+
S s2 = S(cast(int*) 0xDEADBEEF); /* s2 is unsafe, because s2.p is
3116+
unsafe. */
3117+
3118+
union U { int* p; size_t x; }
3119+
U u = U(new int); /* Even though both u.p and u.x are safe, u is unsafe
3120+
because of unsafe aliasing. */
3121+
---
3122+
)
3123+
3124+
$(P A class reference is safe when it is `null` or:)
3125+
$(OL
3126+
$(LI it refers to a valid class instance of the stated type or a
3127+
subtype, and)
3128+
$(LI the values of the instance's accessible fields are safe, and)
3129+
$(LI it does not introduce unsafe aliasing with unions.)
3130+
)
3131+
3132+
$(P A function pointer is safe when it is `null` or it refers to a valid
3133+
function that has the same or a covariant signature.)
3134+
3135+
$(P A `delegate` is safe when:)
3136+
$(OL
3137+
$(LI its `.funcptr` is `null` or refers to a function that matches
3138+
the delegate type, and)
3139+
$(LI its `.ptr` is `null` or refers to a context that is in a format
3140+
expected by the function.)
3141+
)
3142+
3143+
$(H3 $(LNAME2 safe-aliasing, Safe Aliasing))
3144+
3145+
$(P When one memory location is accessible with two different types, that
3146+
aliasing is considered safe in these cases:)
3147+
$(OL
3148+
$(LI both types are `const` or `immutable`; or)
3149+
$(LI one of the types is mutable while the other is a `const`-qualified
3150+
$(DDSUBLINK spec/type, basic-data-types, basic data type); or)
3151+
$(LI both types are mutable basic data types; or)
3152+
$(LI one of the types is a static array type with length zero; or)
3153+
$(LI one of the types is a static array type with non-zero length, and
3154+
aliasing of the array's element type and the other type is safe; or)
3155+
$(LI both types are pointer types, and aliasing of the target types is
3156+
safe, and the target types have the same size.)
3157+
)
3158+
3159+
$(P All other cases of aliasing are considered unsafe.)
3160+
3161+
$(P $(B Note:) Safe aliasing may be exposed to functions with
3162+
$(RELATIVE_LINK2 safe-interfaces, safe interfaces) without affecting their
3163+
guaranteed safety. But when unsafe aliasing is exposed to such functions,
3164+
their safety is no longer guaranteed.)
3165+
3166+
$(P $(B Note:) An aliasing relation being safe does not imply that both
3167+
views of the data have $(RELATIVE_LINK2 safe-values, safe values). That must
3168+
be examined separately when safety is of concern.)
3169+
3170+
$(P Examples:)
3171+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
3172+
---
3173+
void f1(ref ubyte x, ref float y) @safe { x = 0; y = float.init; }
3174+
union U1 { ubyte x; float y; } /* This aliasing is safe. */
3175+
U1 u1;
3176+
f1(u1.x, u1.y); /* So calling f1 like this is ok. */
3177+
3178+
void f2(ref int* x, ref int y) @trusted { x = new int; y = 0xDEADBEEF; }
3179+
union U2 { int* x; int y; } /* This aliasing is unsafe. */
3180+
U2 u2;
3181+
version (none) f1(u2.x, u2.y); /* So calling f2 like this is not ok. */
3182+
---
3183+
)
29553184

29563185
$(H2 $(LNAME2 function-attribute-inference, Function Attribute Inference))
29573186

0 commit comments

Comments
 (0)