Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

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

Abierto
#1,034 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
55/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
c, go
Área
tooling

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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.

Lenguaje dominante
Go
Estrellas
39
Forks
13
Merge medio
1 h 27 min
PR fusionados (30 d)
256

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de goplus/llcppg

Todos los issues de goplus/llcppg

Issues similares

Más issues de Go

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.