1: Sample code that reproduces the problem.
float *itof(int *i)
{
return i; // no warning
}
int main(void)
{
int s = 0, *t;
float *f = itof(&s);
t = f; // no warning
t = itof(f); // no warning
return *f;
}
2: Exact command used to run SDCC on this sample code
sdcc --std=c23 /work/bug.c
3: SDCC version tested (type "sdcc -v" to find it)
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/r800/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502/mos65c02/f8 TD- 4.5.0 #15242 (Linux)
4: Copy of the error message or incorrect output, or a clear description of the observed versus expected behavior.
The C23 constraints on simple assignment (6.5.17.2) say:
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 specification of "compatible types" (6.7.2) says:
Two types are compatible types if they are the same
The specification of "diagnostics" (5.1.1.3) says:
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.
This is an oversimplification, but regardless, float and int are not the same type.
https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf
I am aware that SDCC is not a conforming implementation of C, but from a practical perspective it seems to me that diagnosing assignment/initialisation of incompatible pointer types would be of great benefit to users.
Bugs: #3952
Bugs: #4003
Bugs: #4113
Feature Requests: #659
Feature Requests: #880
By the way, it makes no difference to the behaviour of SDCC if the example is altered to prevent the optimiser from determining the return value at compile time:
Notes:
case '=':indecorateTypeinSDCCast.ccallscompareTypeinSDCCsymt.c, but only outputs diagnostics on complete incompatibility.compareTypein this case forwards tocomparePtrType, which in turn forwards tocompareTypecompareTypedoes not appear to distinguish between explicitly and implicitly castableMaybe we need to introduce another return value for
compareType.This also affects function declaration checking when checking declaration vs. definition:
Does not give any diagnostic.
Still not producing warnings with
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)
I am attaching a proposed bugfix for this issue, created with assistance from Codex. I hope that it will prove acceptable when reviewed by SDCC's maintainers.
Tests and standard headers that provoked previously-undiagnosed and presumably unintentional constraint violations have also been updated to reduce noise in test logs.
I did the following testing of the proposed patch:
i.e.
make -j2
make -C support/regression clean-results
make -C support/regression -j2 test-ucz80
make -C support/valdiag clean
make -C support/valdiag -j2
Summary for 'ucz80': 0 failures, 36740 tests, 6407 test cases, 7347646 bytes, 1613638288 ticks
Summary for 'mcs51': 0 failures, 656 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'mcs51-large': 0 failures, 654 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'mcs51-stack-auto': 0 failures, 655 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'ds390': 0 failures, 642 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'z80': 0 failures, 645 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'z180': 0 failures, 644 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'r2k': 0 failures, 644 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'r4k': 0 failures, 644 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'sm83': 0 failures, 644 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'tlcs90': 0 failures, 644 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'hc08': 0 failures, 643 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 's08': 0 failures, 643 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'mos6502': 0 failures, 643 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'stm8': 0 failures, 646 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'f8': 0 failures, 642 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'pdk13': 0 failures, 645 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'pdk14': 0 failures, 643 tests, 370 test cases, 0 bytes, 0 ticks
Summary for 'pdk15': 0 failures, 641 tests, 370 test cases, 0 bytes, 0 ticks
I think this patch needs rework. It is not a well thought-out complete solution.
I'm finding it hard to arrive at comprehensible solution because of this in
compareTypeExact(which is not the only dead code in that function):
Please find a reworked version of the candidate fix for this bug attached. It has no known dependencies but two other patches depend on it:
the fix for bug #4005 will use the decay and pointer-checking code introduced by #3952.
the fix for bug #4006 will use #3952’s diagnostic result to avoid duplicate diagnostics, and array-decay handling from the fix for bug #4005 .
Last edit: Christopher Bazley 3 days ago
Its a big patch, hope to find time for it on Monday. The library fixes, though, look obviously good, so I've already picked them in [r16959].
Related
Commit: [r16959]
I've looked at the changes to existing regression tests in support/regression. Apparently those just "fix" the code wherever a warning is emitted with [bugs:#3952] fixed.
We need to decide this case-by-case:
#pragma disable_warning, since the warning is expected, not an issue in the test. Or maybe we can keep the tested code by making a change in the infrastructure part instead (like I did for tests-bug-2320.c in the same commit).Related
Bugs: #3952
Commit: [r16960]
Last edit: Philipp Klaus Krause 2 days ago
Hi Philipp,
I don't feel strongly about it but I would like to point out that the simplest fix would have been to add casts as necessary, which is not what I decided to do everywhere.
My assumption was that you do not intentionally test implicitly undefined behaviour, that such behaviour is either unpredictable now or might become unpredictable in future, and therefore that any tests that violate type constraints on assignment do so by accident. That said, I am not familiar with what extension behaviour SDCC might specify that users might choose to exploit.
Unless my changes prevent test cases from exercising the cases they were designed to exercise, I don't see a problem. If they are tests specifically written to exercise constraint violations then that is of course different.
Related
Bugs: #3952
Last edit: Christopher Bazley 2 days ago
"Unless my changes prevent test cases from exercising the cases they were designed to exercise, I don't see a problem.." - then it becomes about knowing what "they were designed to exercise" - usually the regression tests named
*-bug.care derived from the user code that wasn't working as expected by the user, which means some user expected that code to work. Similarly for thegcc-*and thegte/*ones (except that we got them indirectly vie GCC.Thanks for explaining. Please find a modified patch attached that uses
#pragma disable_warning 244to selectively disable diagnostic messages in bug-2632 and four GCC regression tests rather than changing types or adding explicit casts.(replaced attachment at 09:58 on 5 Oct)
Last edit: Christopher Bazley 1 day ago
Thanks. I've picked those regression test changes for [r16962].
However, with the full patch applied I still see lots of warnings for some existing tests (e.g. tests/bug2320.c and tests/bug-3728.c for test-mcs51-small and test-ucz80), some of which look like false positives at first sight.
Related
Commit: [r16962]
I hope this helps.
Thanks. For now, I've merged most of the regression test changes in [r16970]. For the changes in src/SDCCsymt.c, I see a merge conflict.
Regarding the fix for
support/regression/tests/p99-conformance.c: I see the problem in there, and will merge the workaround wit the rest of the patch. That test code was written by Jens Gustedt for his P99 library, you might want to report the bug to him to also get it fixed in upstream P99.Related
Commit: [r16970]