mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/cgo: reject names that are likely to be mangled C name
Fixes #28721 Change-Id: I00356f3a9b0c2fb21dc9c2237dd5296fcb3b319b Reviewed-on: https://go-review.googlesource.com/c/152657 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
897e0807c3
commit
5e1727892b
5 changed files with 55 additions and 1 deletions
|
|
@ -121,6 +121,7 @@ func TestReportsTypeErrors(t *testing.T) {
|
|||
"issue16591.go",
|
||||
"issue18452.go",
|
||||
"issue18889.go",
|
||||
"issue28721.go",
|
||||
} {
|
||||
check(t, file)
|
||||
}
|
||||
|
|
|
|||
29
misc/cgo/errors/src/issue28721.go
Normal file
29
misc/cgo/errors/src/issue28721.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// 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
|
||||
}
|
||||
|
|
@ -145,6 +145,7 @@ func (f *File) ParseGo(name string, src []byte) {
|
|||
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.
|
||||
|
|
@ -181,6 +182,14 @@ func commentText(g *ast.CommentGroup) string {
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -719,6 +719,19 @@ func (p *Package) mangleName(n *Name) {
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -106,13 +106,15 @@ func (r *Ref) Pos() token.Pos {
|
|||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue