Menu

#518 Fix false "declared extern and initialized" error (320) with typeof/auto

open
nobody
None
Front-end
5
3 hours ago
2026-09-05
No

typeofOp() (used to implement C23 typeof, typeof_unqual, and auto type inference) copied the function's return type but only cleared SPEC_SCLS and SPEC_STAT on the copy. It did not clear SPEC_EXTR.

Non-static file-scope function declarations get SPEC_EXTR set to 1 by default on their return type (external_declaration in SDCC.y). When a local variable's type was deduced from a call to such a function via typeof(f()), typeof_unqual(f()), or auto x = f(), that stray extern flag leaked into the deduced type, and the block-scope initializer check in gatherAutoInit() then rejected the initialized variable with:

error 320: block-scope variable 'x' declared extern and intialized

even though the variable was never declared extern.

Fix: clear SPEC_EXTR on the type copy in typeofOp(), alongside the existing SPEC_SCLS/SPEC_STAT resets.

Testing: added support/regression/tests/bug-typeof-extern.c, covering typeof, typeof_unqual, and auto against a non-static function returning a struct. All four sub-tests fail to compile before the fix and pass after.

 ChangeLog:

  * src/SDCCast.c (typeofOp): Clear SPEC_EXTR on the copied type,
    not just SPEC_SCLS/SPEC_STAT. The extern flag set by default on
    the return type of a non-static file-scope function
    (SDCC.y:external_declaration) was leaking into the type deduced
    by typeof/typeof_unqual/auto, causing initialized block-scope
    variables to be misdiagnosed as extern (error 320).
  * support/regression/tests/bug-typeof-extern.c: New regression test.
1 Attachments

Discussion

  • Philipp Klaus Krause

    The test passes for me, even with current SDCC.

     
  • Vladimir Setyaev

    Vladimir Setyaev - 3 hours ago

    I tried commenting out the SPEC_EXTR (spec_type) = 0; line in typeofOp (src/SDCCast.c), rebuilt sdcc, and cleaned the regression cache (gen/, results/ under support/regression) so stale .rel/.ihx/.out artifacts from a previous build wouldn't mask the result. After that, the bug reproduced again both on the dedicated regression test (bug-typeof-extern.c, error 320 on all four cases) and on the actual project. So the fix is still necessary — the earlier "it doesn't reproduce" result was caused by the regression harness reusing cached artifacts from an older build, not by the bug being gone.

     

Log in to post a comment.