-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Open
Labels
NeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.Feedback 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.Issues related to the Go compiler and/or runtime.
Milestone
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.)
avivdolev
Metadata
Metadata
Assignees
Labels
NeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.Feedback 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.Issues related to the Go compiler and/or runtime.
Type
Projects
Status
Triage Backlog