I just updated to the latest SDCC source from SVN (#12740) and now one of my programs does not compile anymore.
It looks like local enum definitions are unknown in deeper block levels.
I stripped down the source to come up with this minimal test to reproduce the issue.
The same code compiles fine with latest release version of SDCC.
unsigned char _sdcc_external_startup(void) {
return 0;
}
void main(void)
{
enum { EV1 = 3, EV2 = 13, EV3 = 7 };
volatile int test1 = EV2; //this works as expected
for(;;){
volatile int test2 = EV2; //BUG: ==> test.c:14: error 20: Undefined identifier 'EV2'
}
}
I bisected the commit and r12555 is the offending commit https://sourceforge.net/p/sdcc/code/12555/
Seems one of the new "leaveBlockScope" function calls is causing the issue for ENUMs
Last edit: Free-PDK 2021-10-18
I've simplified this somewhat:
Apparently, in findSymWithLevel, we don't find EV2 the second time, as the level has changed by then, and when the level doesn't match, some extra things are checked. The one extra check that is failing is for ((symbol *) (bp->sym))->isinscope.
Last edit: Philipp Klaus Krause 2022-02-02
It happens with an explicit enclosing block, too:
So apparently, this bug is not limited to particular block types, but enum scoping in general is broken.
Interestingly, referencing a variable from the outer block works:
Stupid question: Does anything ever actually set
isinscopeto 1 for enums?I believe that isinscope is never set for enums. The symbol tables originally only considered nesting levels to determine if something was still in scope or not. That led to incorrectly reported errors like this:
I added to isinscope flag to try to fix this. The flag is set while recursing down the AST when local variables are discovered in a BLOCK node and cleared when returning upward. Unfortunately I overlooking the possibility of locally scoped enums; these are not recorded in the BLOCK node because they require no allocation.
As a stop-gap measure, isinscope could be set for all enums, which would solve this specific bug at the expense of their scope creeping into adjacent nested scopes within the same function.
I believe that this workaround would be the lesser evil, right now.
It would make sure that code that worked fine with 4.1.0 will work fine with 4.2.0 by restoring the old (but equally buggy) behavior.
Regression fixed in [r13002] so that we return to 4.1.0 behavior for enums. This still leaves some scoping problems, but they are less likely to be encountered.