1: Sample code that reproduces the problem.
struct S1 {
char m[64];
};
char *str_from_struct(const struct S1 *pcs)
{
// valid because of array to pointer decay
static_assert(_Generic(pcs->m,
const char *: 1,
default: 0));
// invalid: array to pointer decay does not remove const
char *m = pcs->m; // constraint violation, no warning
m = pcs->m; // constraint violation, no warning
return pcs->m; // constraint violation, no warning
}
struct S2 {
const char m[64];
};
char *str_from_struct2(struct S2 *pcs)
{
// valid because of array to pointer decay
static_assert(_Generic(pcs->m,
const char *: 1,
default: 0));
// invalid: array to pointer decay does not remove const
char *m = pcs->m; // constraint violation, no warning
m = pcs->m; // constraint violation, no warning
return pcs->m; // constraint violation, no warning
}
char *str_from_str(const char *pcc)
{
static_assert(_Generic(pcc,
const char *: 1,
default: 0));
// invalid: violates constraint on assignment
char *m = pcc; // pointer target lost const qualifier
m = pcc; // pointer target lost const qualifier
return pcc; // pointer target lost const qualifier
}
2: Exact command used to run SDCC on this sample code
sdcc --std=c23 -c /work/bug2.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.21 #16327 (Linux)
4: Copy of the error message or incorrect output, or a clear description of the observed versus expected behavior.
Assignment of an expression of type const char * to an lvalue of type char * (or an equivalent initialisation) is not diagnosed if the assigned value (or initialiser) is the result of array-to-pointer decay and the array is a struct member.
The following (correct) diagnostic messages are produced:
/work/bug2.c:41: warning 196: pointer target lost const qualifier
/work/bug2.c:42: warning 196: pointer target lost const qualifier
/work/bug2.c:43: warning 196: pointer target lost const qualifier
No diagnostic message is produced for the cases where the assigned pointer value originates from array-to-pointer decay of a struct member type (i.e. in str_from_struct and str_from_struct2).
The violated constraint on simple assignment (6.5.17.2) in C23 is:
the left operand has atomic, qualified, or unqualified pointer type, and (considering the type
the left operand would have after lvalue conversion) both operands are pointers to qualified
or unqualified versions of compatible types, and the type pointed to by the left operand has all
the qualifiers of the type pointed to by the right operand
The "Diagnostics" subsection (5.1.1.3 ) of C23 specifies:
A conforming implementation shall produce at least one diagnostic message (identified in an
implementation-defined manner) if a preprocessing translation unit or translation unit contains
a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as
undefined or implementation-defined.
See https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf
I am aware that SDCC is not a conforming C23 compiler, but the lack of diagnostic messages in this specific scenario seems more likely to be accidental than deliberate. Fixing it could help users to find bugs in their programs.
It's probably best to check that the
str_from_arraycode example from the_OptionalTS works as well, if fixing this. It uses pointer-to-array instead of pointer-to-struct-containing-array-member.