1: Sample code that reproduces the problem.
#include <stdlib.h>
// & yields a pointer to non-optional-qualified type
#define optional_cast(p) ((typeof(&*(p)))(p))
// const-qualified referenced type of s is accidental
void free_str_2(_Optional const char *s)
{
free(optional_cast(s)); // constraint violation
}
2: Exact command used to run SDCC on this sample code
sdcc --stack-auto --std=c23 -c free_str_2.c
3: SDCC version tested (type "sdcc -v" to find it)
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/r4k/r5k/r6k/sm83/tlcs90/ez80/z80n/r800/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502/mos65c02/f8/f8l TD- 4.5.24 #16456 (Mac OS X ppc)
4: Copy of the error message or incorrect output, or a clear description of the observed versus expected behavior.
The above example is taken from the Semantics part of the subsection "Typeof specifiers" in the _Optional TS. Specifically:
Because s does not have a variably modified type in the macro-replaced expression (typeof(&(s)))(s)) that results from invocations of the optional_cast macro, the operand of typeof is not evaluated, therefore no diagnostic message is recommended for the lvalue (s) .
The address-of operator is defined as removing the _Optional qualifier from the type of its operand but it must not remove any other qualifiers. The expected type of the argument expression in the free function call is therefore const char *, which violates a constraint on assignment (assuming the free function has the ISO standard parameter type).
SDCC does not report that the const qualifier was lost from the pointer target during the assignment implicit in the function call. That seems like a bug, because the ISO C standard requires a diagnostic message to be produced for every constraint violation.
After further investigation, I don't think this bug is specific to
_Optional: