"issue16591.go",
"issue18452.go",
"issue18889.go",
+ "issue28721.go",
} {
check(t, file)
}
--- /dev/null
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// cgo should reject the use of mangled C names.
+
+package main
+
+/*
+typedef struct a {
+ int i;
+} a;
+void fn(void) {}
+*/
+import "C"
+
+type B _Ctype_struct_a // ERROR HERE
+
+var a _Ctype_struct_a // ERROR HERE
+
+type A struct {
+ a *_Ctype_struct_a // ERROR HERE
+}
+
+var notExist _Ctype_NotExist // ERROR HERE
+
+func main() {
+ _Cfunc_fn() // ERROR HERE
+}
if f.Ref == nil {
f.Ref = make([]*Ref, 0, 8)
}
+ f.walk(ast2, ctxProg, (*File).validateIdents)
f.walk(ast2, ctxProg, (*File).saveExprs)
// Accumulate exported functions.
return strings.Join(pieces, "")
}
+func (f *File) validateIdents(x interface{}, context astContext) {
+ if x, ok := x.(*ast.Ident); ok {
+ if f.isMangledName(x.Name) {
+ error_(x.Pos(), "identifier %q may conflict with identifiers generated by cgo", x.Name)
+ }
+ }
+}
+
// Save various references we are going to need later.
func (f *File) saveExprs(x interface{}, context astContext) {
switch x := x.(type) {
n.Mangle = prefix + n.Kind + "_" + n.Go
}
+func (f *File) isMangledName(s string) bool {
+ prefix := "_C"
+ if strings.HasPrefix(s, prefix) {
+ t := s[len(prefix):]
+ for _, k := range nameKinds {
+ if strings.HasPrefix(t, k+"_") {
+ return true
+ }
+ }
+ }
+ return false
+}
+
// rewriteCalls rewrites all calls that pass pointers to check that
// they follow the rules for passing pointers between Go and C.
// This reports whether the package needs to import unsafe as _cgo_unsafe.
return (*r.Expr).Pos()
}
+var nameKinds = []string{"iconst", "fconst", "sconst", "type", "var", "fpvar", "func", "macro", "not-type"}
+
// A Name collects information about C.xxx.
type Name struct {
Go string // name used in Go referring to package C
Mangle string // name used in generated Go
C string // name used in C
Define string // #define expansion
- Kind string // "iconst", "fconst", "sconst", "type", "var", "fpvar", "func", "macro", "not-type"
+ Kind string // one of the nameKinds
Type *Type // the type of xxx
FuncType *FuncType
AddError bool