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",
|
"issue16591.go",
|
||||||
"issue18452.go",
|
"issue18452.go",
|
||||||
"issue18889.go",
|
"issue18889.go",
|
||||||
|
"issue28721.go",
|
||||||
} {
|
} {
|
||||||
check(t, file)
|
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 {
|
if f.Ref == nil {
|
||||||
f.Ref = make([]*Ref, 0, 8)
|
f.Ref = make([]*Ref, 0, 8)
|
||||||
}
|
}
|
||||||
|
f.walk(ast2, ctxProg, (*File).validateIdents)
|
||||||
f.walk(ast2, ctxProg, (*File).saveExprs)
|
f.walk(ast2, ctxProg, (*File).saveExprs)
|
||||||
|
|
||||||
// Accumulate exported functions.
|
// Accumulate exported functions.
|
||||||
|
|
@ -181,6 +182,14 @@ func commentText(g *ast.CommentGroup) string {
|
||||||
return strings.Join(pieces, "")
|
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.
|
// Save various references we are going to need later.
|
||||||
func (f *File) saveExprs(x interface{}, context astContext) {
|
func (f *File) saveExprs(x interface{}, context astContext) {
|
||||||
switch x := x.(type) {
|
switch x := x.(type) {
|
||||||
|
|
|
||||||
|
|
@ -719,6 +719,19 @@ func (p *Package) mangleName(n *Name) {
|
||||||
n.Mangle = prefix + n.Kind + "_" + n.Go
|
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
|
// rewriteCalls rewrites all calls that pass pointers to check that
|
||||||
// they follow the rules for passing pointers between Go and C.
|
// they follow the rules for passing pointers between Go and C.
|
||||||
// This reports whether the package needs to import unsafe as _cgo_unsafe.
|
// 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()
|
return (*r.Expr).Pos()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nameKinds = []string{"iconst", "fconst", "sconst", "type", "var", "fpvar", "func", "macro", "not-type"}
|
||||||
|
|
||||||
// A Name collects information about C.xxx.
|
// A Name collects information about C.xxx.
|
||||||
type Name struct {
|
type Name struct {
|
||||||
Go string // name used in Go referring to package C
|
Go string // name used in Go referring to package C
|
||||||
Mangle string // name used in generated Go
|
Mangle string // name used in generated Go
|
||||||
C string // name used in C
|
C string // name used in C
|
||||||
Define string // #define expansion
|
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
|
Type *Type // the type of xxx
|
||||||
FuncType *FuncType
|
FuncType *FuncType
|
||||||
AddError bool
|
AddError bool
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue