1: Sample code that reproduces the problem.
struct S
{
char m[64];
};
void from_struct(struct S *p)
{
_Static_assert(_Generic(p->m, char *: 1, default: 0),
"member array did not decay to generic pointer");
}
void from_array(char (*p)[64])
{
_Static_assert(_Generic(*p, char *: 1, default: 0),
"array did not decay to generic pointer");
}
2: Exact command used to run SDCC on this sample code
sdcc -mmcs51 --std-c11 -S decay.c
The issue is also reproducible with -mmcs51 --model-large and -mds390, but not with -mmcs51 --stack-auto.
3: SDCC version tested (type "sdcc -v" to find it)
SDCC : mcs51/ds390/TININative TD- 4.6.2 #16838 (Linux)
published under GNU General Public License (GPL)
4: Copy of the error message or incorrect output, or a clear description of the observed versus expected behavior.
Incorrect output with -mmcs51:
decay.c:14: warning 215: static assertion failed: "array did not decay to generic pointer"
Both p->m and *p designate arrays reached through generic pointers. Array-to-pointer conversion of p->m produces the expected generic char *, whereas conversion of *p produces an address-space-specific pointer: __data char * with the default mcs51 model, and __xdata char * with mcs51 model-large and ds390.
The latter conversion therefore appears to discard the generic address-space provenance carried by p. Besides making the types of otherwise analogous expressions inconsistent, this could affect code generation if an SDCC generic pointer carries address-space information that an address-space-specific pointer does not.
The same behavior occurs without _Optional; it was discovered while preparing a proposed fix and regression tests for bug #4005.
This a has the same root cause as bug #3954. A candidate fix for both issues is attached to that bug.