Commit 5e172789 authored by Hiroshi Ioka's avatar Hiroshi Ioka Committed by Ian Lance Taylor

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: default avatarIan Lance Taylor <iant@golang.org>
parent 897e0807
...@@ -121,6 +121,7 @@ func TestReportsTypeErrors(t *testing.T) { ...@@ -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)
} }
......
// 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) { ...@@ -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 { ...@@ -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) { ...@@ -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 { ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment