This is related to, but not identical to, feature request #1020. Both of them concern unwanted diagnostics. Unlike request #1020, the draft technical specification of _Optional does not yet include an example of type-based pointer aliasing analysis, but that is an omission that should arguably be corrected.
The sample code given in request #1020 is just one case of a more general potential feature, because restrict is not necessarily required for a C compiler to be able to infer that two pointers cannot alias without invoking undefined behaviour.
Consider the following example:
void
noalias (_Optional int **ppoi, _Optional float **ppof)
{
// constrains *ppoi to non-null on the fallthrough path
if (!*ppoi)
return;
**ppoi = 1; // no recommended diagnostic
*ppof = nullptr; // non-null constraint on *ppoi is lost because SDCC conservatively assumes *ppof can alias *ppoi
**ppoi = 2; // unwanted diagnostic
}
SDCC 4.6.0 produces an unwanted diagnostic message for the final statement, **ppoi = 2;:
<source>:10: warning 355: pointer to _Optional could not be proven to be non-null at dereference
https://godbolt.org/z/rjdf7x9KG
That diagnostic messsage can be avoided by using an extra local variable:
void
noalias (_Optional int **ppoi, _Optional float **ppof)
{
_Optional int *poi = *ppoi;
// constrains poi to non-null on the fallthrough path
if (!poi)
return;
*poi = 1; // no recommended diagnostic
*ppof = nullptr; // non-null constraint on *ppoi is unaffected because *ppof cannot alias poi
*poi = 2; // no diagnostic
}
SDCC 4.6.0 produces no diagnostic message for the above translation unit: https://godbolt.org/z/6MPshYYjz
However, the necessity for this workaround increases the friction caused by the _Optional keyword, which could discourage programmers from using it and thereby increase the likelihood of undiagnosed null pointer dereferences.
The rules relevant to type-based aliasing analysis are specified by 6.5.1 in the C2Y standard:
An object shall have its stored value accessed only by an lvalue expression that has one of the
following types:71)
— a type compatible with the effective type of the object,
— a qualified version of a type compatible with the effective type of the object,
— the signed or unsigned type corresponding to a type compatible with the underlying type of
the effective type of the object,
— the signed or unsigned type corresponding to a type compatible with a qualified version of
the underlying type of the effective type of the object,
— a byte type, or
— an aggregate or union type that includes one of the aforementioned types among its members
(including, recursively, a member of a subaggregate or contained union).
When used for optimisation purposes, the strict aliasing rules can cause mis-compilation of non-conforming programs; in contrast, the only effect of implementing this feature request would be to suppress diagnostic messages. The casts that are usually needed to violate the strict aliasing rules already serve to suppress diagnostic messages, therefore that choice seems reasonable to me.