]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: reject names that are likely to be mangled C name
authorHiroshi Ioka <hirochachacha@gmail.com>
Tue, 4 Dec 2018 23:01:07 +0000 (08:01 +0900)
committerIan Lance Taylor <iant@golang.org>
Wed, 5 Dec 2018 14:12:14 +0000 (14:12 +0000)
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>
misc/cgo/errors/errors_test.go
misc/cgo/errors/src/issue28721.go [new file with mode: 0644]
src/cmd/cgo/ast.go
src/cmd/cgo/gcc.go
src/cmd/cgo/main.go

index 0d7ca4cf9d89c5fedef1e1e1497c1afc4587e93d..d2a72a46f430ab07624975335876277e986b4d17 100644 (file)
@@ -121,6 +121,7 @@ func TestReportsTypeErrors(t *testing.T) {
                "issue16591.go",
                "issue18452.go",
                "issue18889.go",
+               "issue28721.go",
        } {
                check(t, file)
        }
diff --git a/misc/cgo/errors/src/issue28721.go b/misc/cgo/errors/src/issue28721.go
new file mode 100644 (file)
index 0000000..0eb2a92
--- /dev/null
@@ -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
+}
index 06058cb570d4fe4d7287169a2634b45edd03a20e..83d727a8a5da6846865076daff262df8ef7b01f9 100644 (file)
@@ -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) {
index 4464b840dd69c0a7aad50300d232af6f97416a17..b59bfe68fe10a6015710b4e0e6f0cb9747d6bf45 100644 (file)
@@ -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.
index 7a845b17a4e7741eacaf142c797044490bcf64bc..80435b0634d901e98f104ec7a65975b450008011 100644 (file)
@@ -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