Open
Description
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
Labels
Type
Projects
Status
Triage Backlog