Skip to content

cmd/cgo: cgo allows creating values of incomplete struct/union type #40507

Open
@mdempsky

Description

@mdempsky

This program builds, but fails at runtime:

// x.go
package main

// struct s;
// union u;
// extern void f(struct s *, union u *);
import "C"

func main() {
	C.f(new(C.struct_s), new(C.union_u))
}
// x.c
#include <assert.h>

struct s { int x; };
union u { long x; };

void f(struct s *sp, union u *up) {
  if (sp && up) {
    assert((void *)sp != (void *)up);
  }
}

This is because cgo defines incomplete struct/union types like C.struct_s and C.union_u as struct{}, rather than giving an error. So the new(C.struct_s) and new(C.union_u) end up both allocating as zero-size objects.

I think this program shouldn't build at all.

One reasonable fix would be to disallow incomplete C.struct_* or C.union_* references outside of a pointer type. This might have false positives for things like:

package p

// struct s;
import "C"

type s C.struct_s
var _ *s

A more invasive but more robust fix would be a //go:cgo_incomplete directive that tells the compiler it shouldn't allow values of that type.

/cc @ianlancetaylor

(Noted while working on fix for #40494.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Status

    Triage Backlog

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions