1: Sample code that reproduces the problem.
struct S
{
char padding;
_Optional int *p;
};
int read_value(volatile struct S *s)
{
if (s->p)
return *s->p;
return 0;
}
2: Exact command used to run SDCC on this sample code
sdcc -mz80 --std-c99 -c volatile-member.c
3: SDCC version tested
SDCC trunk r16999.
4: Copy of the error message or incorrect output, or a clear description of the observed versus expected behavior.
There is no warning about *s->p whereas I expected warning 355. Access through a pointer to a volatile structure makes a pointer member volatile. Use of the pointer member's value in the if statement's controlling expression and the dereference of the same pointer in the return expression read the value of that member separately; the second read may yield null even if the first did not. The guarding if statement therefore does not establish that the value used for dereference is non-null.
The same omission occurs with z80, mcs51, r2k, stm8, s08 and pdk14.
Removing padding makes trunk warn on all six targets. This layout-dependent warning masks the underlying mishandling of volatile qualification. Fixing the separate first-member problem reported in [bugs:#4148] also removes that warning unless the volatile issue is fixed.
In other words, we do want a diagnostic message to be produced for the sample code, but we do not want it to be produced for the wrong reason.
Related
Bugs:
#4148Please consider the attached candidate patch.
While this doesn't apply for me against current trunk, I applied the src/SDCCicode.c changes manually to test, and it looks good to me. I did a few quick tests using hand-written testcases around struct with
volatilemembers, or members that are pointers tovolatile, and did not notice a regression wjen reading the resulting .asm and looking at iCode and AST dumps.In general, I am worried about SDCC bugs wrt. volatile, since they tend to be hard to test for. So I welcome this testing opportunity
_Optionalgives us here.If you can think of further tests relating to volatile that we could get with
_Optional, please look into that (though that might be beyond the scope of this ticket).Last edit: Philipp Klaus Krause 2026-10-18
@spth you were right about this:
Codex claims to have found one other similar bug:
s->a[1]loses its second read.I have not yet confirmed it or reported it separately.
@spth I have since reported the newly-discovered bug in compilation of the sample code above as [bugs:#4161].
Related
Bugs:
#4161Fixed by [r17035].
Related
Commit: [r17035]
I see a code size regression for Rabbit ports.
I've looked into one affected line in the Dhrystone benchmark, line 105 in
dhry_1.c:Ptr_Glob is a pointer to a struct with three members, one of them a union. Previously, a peephole optimizer rules was able to optimize out a read from the memory location at which this pointer is stored:
Now, this read is kept. Apparently the heuristics the peephole optimizer uses are not good enough to prove that the pointer is not volatile.
Don't know if this issue is worth fixing, but I think we should at least look into it a bit. There are more code size regressions than that one line, but this is the only one I looked into a bit more so far.
P.S.: We see the increase in code size e.g. at https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc-extra/historygraphs/dhrystone-r4k-size.svg
Last edit: Philipp Klaus Krause 2026-10-21
Hi @spth, is this candidate fix for the regression any use? I asked Codex to investigate and it has produced a patch.
IMO, relying on
line->icis too risky, since after multiple application of peephole optimizer rules that information might have lost too much meaning. Could we try to look up the symbol in the symbol table, like we do at call instructions (to find out which registers hold register parameters, e.g. in src/z80/peep.c) instead?How about this version?
Last edit: Christopher Bazley 2026-10-21
Looks good to me, and works fine for me (for Dhrystone, and the ucz80 and ucr3ka regression tests pass). This should solve the found issue for the z80-related ports.
We probably want this for some other ports, such as stm8, too.
P.S.: possibly introduce a helper function that find the symbol from const char * pointer into an asm line (could return NULL if not found), which we could then use both in the z80 path, in the stm8 path, and later also in the peep.c files where we look up function symbols to determine the register parameters.
Last edit: Philipp Klaus Krause 2026-10-21
Thanks for the review, @spth. The approved patch is committed as [r17071].
I have a pending follow-up patch for that. During the development and testing of that follow-up patch, [bugs:#4202], [bugs:#4203] and [bugs:#4204] were discovered.
Related
Bugs:
#4202Bugs:
#4203Bugs:
#4204Commit: [r17071]
@spth please review the attached patch to implement the above requested change. It depends on the unreviewed patch to fix [bugs:#4202] and friends.
Related
Bugs:
#4202Attaching the same patch rebased on the updated patch to fix [bugs:#4202] and friends.
Related
Bugs:
#4202With your patch for [bugs:#4202] in, I think we could just ditch the old
funcUsesVolatileandglobal_not_volatile, and usemightBeVolatileAccessor-ed over the lines in question instead? That should makenotVolatileconditions in peephole optimizer rules even more accurate.Related
Bugs:
#4202@spth It wasn't quite that straightforward. Codex found a regression in code generation for STM8, caused by removing
funcUsesVolatile:The attached patch is therefore a necessary prerequisite for the changes that you suggested. I think it's relatively safe on its own because it merely has the potential to suppress an optimisation.
Last edit: Christopher Bazley 2026-10-23
@spth Here's the follow-up patch to make the changes that you suggested.
Clearly an improvement, though that parsing with ISCHARALNUM feels a bit crude - it might surprise users that some optimization gets disabled when they use non-ascii characters in identifiers. Don't know if it is worth putting more effort into parsing symbol names here, though.
Thanks. Merged as [r17081].
Related
Commit: [r17081]
Still, could we try to replace that loop
by whatever sdas uses to parse the symbol name? It feels inelegant to have the handling of
volatiledepend on the spelling of identifiers (and if a user runs notices it, we'll probably get a bug report).Hi @spth, I agree that it is inelegant but I don't understand the reason for keeping this bug open, given that the code that you want improved has been present in one form or another since r2842 (Fri, 22 Aug 2003).
If you think it's liable to be reported as a bug then you could report it as a bug or feature request with its own instructions to reproduce the issue.
Is there something I missed? Did I cause a regression by fixing this bug?
I've made that into a new feature request: [feature-requests:#1042].
Related
Feature Requests: #1042
Looks ok to me.