Summary
Two remaining Go 1.26 errorcheck groups need explicit decisions before their xfails can be removed:
- 39 cases already match the primary gc/GOROOT diagnostic, but LLGo emits additional parser-recovery or follow-on type-checker diagnostics.
fixedbugs/issue20780.go expects gc's 1 GiB stack-frame rejection, but that policy may not apply to LLGo's pthread and heap-lowered aggregate model.
These are separate implementation questions. This issue tracks the evidence and desired boundaries without assuming they should share a fix.
1. Remaining syntax/recovery diagnostics
A focused run of the current Go 1.26 errorcheck xfails found 39 pure "expected diagnostic matched, extra diagnostics remained" cases. The baseline contained 233 extra diagnostic lines. An exact-string map deduplication experiment reduced that output to 194 lines but made 0 of the 39 cases pass, so ordinary duplicate removal is not sufficient.
Representative behavior:
syntax/vareq1.go: gc reports syntax error: unexpected { after top level declaration; the later parser pass also reports expected ';', found '{'.
syntax/vareq.go: one gc syntax diagnostic is followed by three parser recovery diagnostics and the type-checker follow-on declared and not used: x.
fixedbugs/bug388.go and runtime.go contain mixed parser/type-checker follow-on output rather than parser-only noise.
The loader already preserves diagnostic kinds (ListError, ParseError, and TypeError) in internal/packages/load.go, but internal/build/build.go currently prints every accumulated package error. The exact same-file/same-line pairing added by #2105 is intentionally narrow and handles only one secondary recovery diagnostic per primary. Multi-diagnostic cases cannot be resolved by adding one more text pair.
The 39 cases are:
fixedbugs/issue23664.go
fixedbugs/issue33386.go
fixedbugs/bug349.go
fixedbugs/issue23587.go
syntax/semi7.go
fixedbugs/bug274.go
fixedbugs/issue18092.go
fixedbugs/bug388.go
switch2.go
fixedbugs/issue13319.go
syntax/semi5.go
fixedbugs/issue13274.go
fixedbugs/issue4405.go
syntax/semi4.go
fixedbugs/issue13273.go
syntax/semi3.go
fixedbugs/issue19667.go
syntax/semi2.go
runtime.go
fixedbugs/issue13248.go
fixedbugs/issue14520.go
fixedbugs/issue17328.go
syntax/semi1.go
syntax/initvar.go
fixedbugs/bug050.go
bombad.go
fixedbugs/bug435.go
fixedbugs/issue14006.go
fixedbugs/issue22581.go
syntax/ddd.go
syntax/composite.go
fixedbugs/bug121.go
fixedbugs/bug228.go
syntax/chan1.go
fixedbugs/issue18747.go
fixedbugs/issue11610.go
fixedbugs/issue22164.go
syntax/vareq1.go
syntax/vareq.go
Likely investigation boundary: filter downstream recovery diagnostics at the final user-visible diagnostic boundary when an authoritative driver diagnostic already exists. Any filter must preserve independent parse/type errors rather than suppressing all ParseError or TypeError values unconditionally.
The superficially related fixedbugs/issue13266.go, fixedbugs/issue4776.go, and fixedbugs/issue20789.go are not in this group: they still have a missing expected diagnostic or mismatched wording.
2. issue20780 and the 1 GiB stack-frame policy
The upstream test is:
type Big = [400e6]byte
func f() { // GC_ERROR "stack frame too large"
g(h(), h())
}
func g(Big, Big)
func h() Big
Go 1.26.3 reports:
issue20780.go:14:6: stack frame too large (>1GB): 762 MB locals + 0 MB args + 762 MB callee
The current LLGo tool compile exits successfully with no output.
gc's check is tied to its own logical frame layout, growing goroutine stack, assembler limits, and runtime stack ceiling. LLGo lowers aggregate returns larger than MaxImplicitStackVarSize through runtime.AllocU; on ordinary system targets this is a BDWGC heap allocation. BDWGC conservatively scans the native thread stack as a root range and does not require a Go-style pointer bitmap proportional to the frame.
LLGo also uses native pthread stacks for goroutines. pthread/OS stack allocation already has a platform default or an explicitly configured size (-pthread-stack-size). A fixed 1 GiB frontend check therefore may be redundant, may not reflect the actual pthread limit, and does not describe the physical LLGo frame produced after LLVM lowering. Bare-metal targets have much smaller fixed stacks and use tinygogc, so 1 GiB is not a useful safety threshold there either.
Open questions:
- Should
fixedbugs/issue20780.go remain an acknowledged gc-specific xfail instead of emulating a diagnostic for a frame LLGo does not generate?
- If LLGo needs stack safety diagnostics, should they use LLVM's final machine-frame size and the selected target/pthread stack budget instead of gc's 1 GiB logical-frame rule?
- Should
llgo tool compile compatibility diagnostics be kept separate from target-aware build safety checks?
Scope
- Resolve the shared output policy for the 39 syntax/recovery cases without per-file xfail workarounds.
- Decide whether
issue20780 is applicable to LLGo before implementing behavior.
- Do not treat gc-only optimization/debug diagnostics or the three wording/missing-diagnostic cases above as part of the 39-case fix.
Related: #2062 tracked complete Go 1.26 GOROOT coverage; #2105 implemented the existing narrow parser-recovery pairing.
Summary
Two remaining Go 1.26
errorcheckgroups need explicit decisions before their xfails can be removed:fixedbugs/issue20780.goexpects gc's 1 GiB stack-frame rejection, but that policy may not apply to LLGo's pthread and heap-lowered aggregate model.These are separate implementation questions. This issue tracks the evidence and desired boundaries without assuming they should share a fix.
1. Remaining syntax/recovery diagnostics
A focused run of the current Go 1.26
errorcheckxfails found 39 pure "expected diagnostic matched, extra diagnostics remained" cases. The baseline contained 233 extra diagnostic lines. An exact-string map deduplication experiment reduced that output to 194 lines but made 0 of the 39 cases pass, so ordinary duplicate removal is not sufficient.Representative behavior:
syntax/vareq1.go: gc reportssyntax error: unexpected { after top level declaration; the later parser pass also reportsexpected ';', found '{'.syntax/vareq.go: one gc syntax diagnostic is followed by three parser recovery diagnostics and the type-checker follow-ondeclared and not used: x.fixedbugs/bug388.goandruntime.gocontain mixed parser/type-checker follow-on output rather than parser-only noise.The loader already preserves diagnostic kinds (
ListError,ParseError, andTypeError) ininternal/packages/load.go, butinternal/build/build.gocurrently prints every accumulated package error. The exact same-file/same-line pairing added by #2105 is intentionally narrow and handles only one secondary recovery diagnostic per primary. Multi-diagnostic cases cannot be resolved by adding one more text pair.The 39 cases are:
Likely investigation boundary: filter downstream recovery diagnostics at the final user-visible diagnostic boundary when an authoritative driver diagnostic already exists. Any filter must preserve independent parse/type errors rather than suppressing all
ParseErrororTypeErrorvalues unconditionally.The superficially related
fixedbugs/issue13266.go,fixedbugs/issue4776.go, andfixedbugs/issue20789.goare not in this group: they still have a missing expected diagnostic or mismatched wording.2.
issue20780and the 1 GiB stack-frame policyThe upstream test is:
Go 1.26.3 reports:
The current LLGo
tool compileexits successfully with no output.gc's check is tied to its own logical frame layout, growing goroutine stack, assembler limits, and runtime stack ceiling. LLGo lowers aggregate returns larger than
MaxImplicitStackVarSizethroughruntime.AllocU; on ordinary system targets this is a BDWGC heap allocation. BDWGC conservatively scans the native thread stack as a root range and does not require a Go-style pointer bitmap proportional to the frame.LLGo also uses native pthread stacks for goroutines. pthread/OS stack allocation already has a platform default or an explicitly configured size (
-pthread-stack-size). A fixed 1 GiB frontend check therefore may be redundant, may not reflect the actual pthread limit, and does not describe the physical LLGo frame produced after LLVM lowering. Bare-metal targets have much smaller fixed stacks and usetinygogc, so 1 GiB is not a useful safety threshold there either.Open questions:
fixedbugs/issue20780.goremain an acknowledged gc-specific xfail instead of emulating a diagnostic for a frame LLGo does not generate?llgo tool compilecompatibility diagnostics be kept separate from target-aware build safety checks?Scope
issue20780is applicable to LLGo before implementing behavior.Related: #2062 tracked complete Go 1.26 GOROOT coverage; #2105 implemented the existing narrow parser-recovery pairing.