I am attaching a proposed implementation of this feature request, created with assistance from Codex. I hope that it will prove acceptable when reviewed by SDCC's maintainers.
The first version made an ordinary block-scope function declaration
implicitly extern in yyparse() declaration action ->
prepareDeclarationSymbol(). It applied only when SPEC_SCLS was S_FIXED, but that was too restrictive because SDCC also stores
target-specific address spaces such as __xdata in SPEC_SCLS. None of
the tests produced by Codex revealed that.
A handwritten extra test of __xdata int f(void) at block scope
showed that such declarations could still be mistaken for automatic
objects, so the bogus S_FIXED restriction was removed.
The new test also exposed a deeper problem with --stack-auto: even
explicitly extern declarations such as extern __xdata int f(void)
were subject to checks intended for automatic objects. The next
version therefore excluded functions from several automatic-object
checks in a later call chain: yyparse() function_definition action ->
createFunction() -> processBlockVars() -> allocVariables() ->
checkDecl() -> checkSClass(). That worked, but further complicated
already-repetitious if conditions in the modified function and
described the exception rather than the rule.
I investigated whether it would be practical to reduce repetition
by use of an early-return from checkSClass() without significant
refactoring. It was not.
The final approach uses IS_AUTO(sym) in checkSClass() instead. IS_AUTO(sym) means that the symbol is at block scope and is neither
static nor extern. prepareDeclarationSymbol() has already marked an
ordinary block-scope function declaration as extern, so IS_AUTO(sym)
excludes it without a separate function check.
Using IS_AUTO(sym) consistently also fixes block-scope extern
object declarations: SDCC 4.6.0 incorrectly rejects a declaration such as extern __xdata int object when compiled with options -mmcs51 --stack-auto, because it wrongly sets E_AUTO_ASSUMED. After confirming
that fact, I added another new handwritten test to the set of new
tests.
I did the following testing of the patch:
complete diagnostic-validation results (support/valdiag) for the default targets.
complete runtime regression (support/regression) results for ucz80.
I have a fix for this that I am testing.
I am attaching a proposed implementation of this feature request, created with assistance from Codex. I hope that it will prove acceptable when reviewed by SDCC's maintainers.
The first version made an ordinary block-scope function declaration
implicitly extern in
yyparse() declaration action -> prepareDeclarationSymbol(). It applied only whenSPEC_SCLSwasS_FIXED, but that was too restrictive because SDCC also storestarget-specific address spaces such as
__xdatainSPEC_SCLS. None ofthe tests produced by Codex revealed that.
A handwritten extra test of
__xdata int f(void)at block scopeshowed that such declarations could still be mistaken for automatic
objects, so the bogus
S_FIXEDrestriction was removed.The new test also exposed a deeper problem with
--stack-auto: evenexplicitly extern declarations such as
extern __xdata int f(void)were subject to checks intended for automatic objects. The next
version therefore excluded functions from several automatic-object
checks in a later call chain:
yyparse() function_definition action -> createFunction() -> processBlockVars() -> allocVariables() -> checkDecl() -> checkSClass(). That worked, but further complicatedalready-repetitious
ifconditions in the modified function anddescribed the exception rather than the rule.
I investigated whether it would be practical to reduce repetition
by use of an early-return from
checkSClass()without significantrefactoring. It was not.
The final approach uses
IS_AUTO(sym)incheckSClass()instead.IS_AUTO(sym)means that the symbol is at block scope and is neitherstatic nor extern.
prepareDeclarationSymbol()has already marked anordinary block-scope function declaration as extern, so
IS_AUTO(sym)excludes it without a separate function check.
Using
IS_AUTO(sym)consistently also fixes block-scope externobject declarations: SDCC 4.6.0 incorrectly rejects a declaration such as
extern __xdata int objectwhen compiled with options-mmcs51 --stack-auto, because it wrongly setsE_AUTO_ASSUMED. After confirmingthat fact, I added another new handwritten test to the set of new
tests.
I did the following testing of the patch:
i.e.
Summary for 'ucz80': 0 failures, 36740 tests, 6407 test cases, 7347620 bytes, 1613638336 ticks
Summary for 'mcs51': 0 failures, 642 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'mcs51-large': 0 failures, 640 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'mcs51-stack-auto': 0 failures, 641 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'ds390': 0 failures, 628 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'z80': 0 failures, 631 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'z180': 0 failures, 630 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'r2k': 0 failures, 630 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'r4k': 0 failures, 630 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'sm83': 0 failures, 630 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'tlcs90': 0 failures, 630 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'hc08': 0 failures, 629 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 's08': 0 failures, 629 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'mos6502': 0 failures, 629 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'stm8': 0 failures, 632 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'f8': 0 failures, 628 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'pdk13': 0 failures, 631 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'pdk14': 0 failures, 629 tests, 364 test cases, 0 bytes, 0 ticks
Summary for 'pdk15': 0 failures, 627 tests, 364 test cases, 0 bytes, 0 ticks
Last edit: Christopher Bazley 2026-09-13