Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

fix(cl): union bit-fields generate incorrect reference accessors and duplicate methods

Aperta
#1,034 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
55/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
c, go
Ambito
tooling

Direzione di ricerca

Start in cl/union.go at initUnionType and genUnionAccessor, then read cl/bitfield.go to follow the existing getter/setter convention. Reproduce with either C input and run llcppg -v generated followed by llgo build ./generated; inspect generated accessors and add focused fixtures in the existing _testc or _testcpp harness. Done means named fields use width and signedness correctly, unnamed fields emit no methods, and the generated code compiles.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug

Problem

Union bit-fields currently take the ordinary reference-accessor path. This causes two distinct problems:

  1. Named bit-fields get pointers to whole integers rather than width-aware accessors.
  2. Unnamed/zero-width bit-fields get empty-suffix methods; multiple such fields produce duplicate XGof_ref_ declarations and the generated package fails to compile.

This is an implementation bug under the existing bit-field contract in #770, tracked separately from the broader generation proposal #1032.

Verified environment

  • llcppg snapshot: 6950e22b8e0c2008384bc06d02575c03e20323a2 (the #1031 branch snapshot).
  • Linux/amd64, Clang/LLVM 22.1.8.
  • LLGo b86d349178d610e6b15e95c2a5fdfcb130d09fa1, github.com/goplus/lib v0.6.1.

Both C inputs below passed the strict C11 syntax check. The report uses the saved generation/build results from that snapshot; it does not claim fresh validation of a newer main or other platforms. The named-field defect is established by the emitted accessors and source path, not by a claimed runtime test.

Case 1: named union bit-fields lose their access semantics

C input:

union Owner {
    unsigned int a : 1;
    unsigned int b : 3;
    int signed_value : 5;
};

Actual generated Go (package/import boilerplate omitted):

type Owner struct {
    _xgo_union [1]uint32
}

func (p *Owner) XGof_ref_a() *c.Uint {
    return (*c.Uint)(unsafe.Pointer(p))
}
func (p *Owner) XGof_ref_b() *c.Uint {
    return (*c.Uint)(unsafe.Pointer(p))
}
func (p *Owner) XGof_ref_signed_value() *c.Int {
    return (*c.Int)(unsafe.Pointer(p))
}

Generation exits 0 and the generated package builds with LLGo, but these are whole-integer accesses. They do not mask writes to widths 1/3/5, preserve unrelated bits during a field assignment, or sign-extend a five-bit signed read. A C bit-field is not an addressable ordinary integer member.

All three fields being at bit offset zero is correct for a union; ignoring their different widths and signedness is not.

Case 2: unnamed and zero-width fields produce duplicate methods

C input:

union Owner {
    unsigned int : 3;
    unsigned int value : 5;
    unsigned int : 0;
};

Actual generated Go (package/import boilerplate omitted):

type Owner struct {
    _xgo_union [1]uint32
}

func (p *Owner) XGof_ref_() *c.Uint {
    return (*c.Uint)(unsafe.Pointer(p))
}
func (p *Owner) XGof_ref_value() *c.Uint {
    return (*c.Uint)(unsafe.Pointer(p))
}
func (p *Owner) XGof_ref_() *c.Uint {
    return (*c.Uint)(unsafe.Pointer(p))
}

Generation again exits 0. Building the full generated file fails with:

generated/in.go:20:17: method Owner.XGof_ref_ already declared at generated/in.go:14:17
cannot build SSA for package example.com/scalarprobe/c/generated
cannot build SSA for packages

Unnamed and zero-width bit-fields have no callable member names. They must not become methods with an empty suffix.

Reproduction

Use either input independently as include/in.h in an isolated fixture directory.

llcppg.cfg:

{"Name":"scalarprobe","Language":"c","Dir":"./include"}

go.mod:

module example.com/scalarprobe/c

go 1.23

require github.com/goplus/lib v0.6.1

With llcppg built from the stated snapshot using LLGo, prepare the dependency checksums and run:

go mod download github.com/goplus/lib
llcppg -v generated
llgo build ./generated

The module-download command only prepares dependency metadata; compilation uses LLGo. Inspect the generated methods for case 1 even though the build passes.

Source path

In the inspected cl/union.go, initUnionType collects each Cursor_FieldDecl and later calls genUnionAccessor for it. That accessor derives a name from the field spelling and casts the union base to a pointer to the field's whole declared type. It does not choose a bit-field path based on bit offset, width, signedness, or whether there is a member name.

The nearby comment says bit-fields are skipped, but the recorded output shows that the implementation does not enforce that distinction.

The existing struct bit-field path in cl/bitfield.go already uses github.com/goplus/lib/c/bitfield and the getter/setter convention.

Expected behavior and proposed fix boundary

  • Named union bit-fields use the existing XGof_get_<member> / XGof_set_<member> contract from #770, not XGof_ref_<member>.
  • Use the actual target bit offset, width and signedness. Reads zero/sign-extend as appropriate; writes update only the field's bits.
  • Unnamed and zero-width bit-fields contribute any required layout effects but generate no accessors.
  • Ordinary non-bit-field union members retain their reference accessors and the union retains one shared storage block.
  • Reuse the existing bit-field generation semantics from cl/bitfield.go; distinguish bit-fields before selecting accessors in cl/union.go. No new accessor family is needed.

Focused fixture coverage should include signed/unsigned named fields, unnamed and zero-width fields, mixed ordinary/bit-field union members, and promoted nested bit-fields with the correct receiver-relative offset. Generated code must compile; width/sign behavior and preservation of unrelated bits also need checks, since compilation alone misses case 1. Keep fixture work in the existing _testc/_testcpp harnesses and do not assume additional platform coverage from these Linux/amd64 results.

No implementation change is included in this report.

Lingua principale
Go
Stelle
39
Fork
13
Merge medio
1h 27m
PR unite (30g)
256

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di goplus/llcppg

Tutte le issue di goplus/llcppg

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.