Skip to content

Commit 5e17278

Browse files
hirochachachaianlancetaylor
authored andcommitted
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>
1 parent 897e080 commit 5e17278

File tree

5 files changed

+55
-1
lines changed

5 files changed

+55
-1
lines changed

misc/cgo/errors/errors_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ func TestReportsTypeErrors(t *testing.T) {
121121
"issue16591.go",
122122
"issue18452.go",
123123
"issue18889.go",
124+
"issue28721.go",
124125
} {
125126
check(t, file)
126127
}

misc/cgo/errors/src/issue28721.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// cgo should reject the use of mangled C names.
6+
7+
package main
8+
9+
/*
10+
typedef struct a {
11+
int i;
12+
} a;
13+
void fn(void) {}
14+
*/
15+
import "C"
16+
17+
type B _Ctype_struct_a // ERROR HERE
18+
19+
var a _Ctype_struct_a // ERROR HERE
20+
21+
type A struct {
22+
a *_Ctype_struct_a // ERROR HERE
23+
}
24+
25+
var notExist _Ctype_NotExist // ERROR HERE
26+
27+
func main() {
28+
_Cfunc_fn() // ERROR HERE
29+
}

src/cmd/cgo/ast.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ func (f *File) ParseGo(name string, src []byte) {
145145
if f.Ref == nil {
146146
f.Ref = make([]*Ref, 0, 8)
147147
}
148+
f.walk(ast2, ctxProg, (*File).validateIdents)
148149
f.walk(ast2, ctxProg, (*File).saveExprs)
149150

150151
// Accumulate exported functions.
@@ -181,6 +182,14 @@ func commentText(g *ast.CommentGroup) string {
181182
return strings.Join(pieces, "")
182183
}
183184

185+
func (f *File) validateIdents(x interface{}, context astContext) {
186+
if x, ok := x.(*ast.Ident); ok {
187+
if f.isMangledName(x.Name) {
188+
error_(x.Pos(), "identifier %q may conflict with identifiers generated by cgo", x.Name)
189+
}
190+
}
191+
}
192+
184193
// Save various references we are going to need later.
185194
func (f *File) saveExprs(x interface{}, context astContext) {
186195
switch x := x.(type) {

src/cmd/cgo/gcc.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,19 @@ func (p *Package) mangleName(n *Name) {
719719
n.Mangle = prefix + n.Kind + "_" + n.Go
720720
}
721721

722+
func (f *File) isMangledName(s string) bool {
723+
prefix := "_C"
724+
if strings.HasPrefix(s, prefix) {
725+
t := s[len(prefix):]
726+
for _, k := range nameKinds {
727+
if strings.HasPrefix(t, k+"_") {
728+
return true
729+
}
730+
}
731+
}
732+
return false
733+
}
734+
722735
// rewriteCalls rewrites all calls that pass pointers to check that
723736
// they follow the rules for passing pointers between Go and C.
724737
// This reports whether the package needs to import unsafe as _cgo_unsafe.

src/cmd/cgo/main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,15 @@ func (r *Ref) Pos() token.Pos {
106106
return (*r.Expr).Pos()
107107
}
108108

109+
var nameKinds = []string{"iconst", "fconst", "sconst", "type", "var", "fpvar", "func", "macro", "not-type"}
110+
109111
// A Name collects information about C.xxx.
110112
type Name struct {
111113
Go string // name used in Go referring to package C
112114
Mangle string // name used in generated Go
113115
C string // name used in C
114116
Define string // #define expansion
115-
Kind string // "iconst", "fconst", "sconst", "type", "var", "fpvar", "func", "macro", "not-type"
117+
Kind string // one of the nameKinds
116118
Type *Type // the type of xxx
117119
FuncType *FuncType
118120
AddError bool

0 commit comments

Comments
 (0)