aboutsummaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorwolf1996 <ksgiv37@gmail.com>2020-11-13 14:30:15 +0300
committerIan Lance Taylor <iant@golang.org>2021-04-05 19:29:17 +0000
commitd5b9dc1317e3d898650fcb6e417f03b00e69270b (patch)
tree31de46d19152a8aa66f64a205fe4981c87ba4b46 /misc
parente985245cd520cabe4bd3d99058d1089aac50cf45 (diff)
downloadgo-d5b9dc1317e3d898650fcb6e417f03b00e69270b.tar.gz
go-d5b9dc1317e3d898650fcb6e417f03b00e69270b.zip
cmd/cgo: pass end position info for C function arguments.
Pass information about original end position for c function arguments processed in pointer checking generated code. Fixes #42580 Change-Id: Ic8a578168362f0ca6055064dbbea092ad37477a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/269760 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Dmitri Shuralyov <dmitshur@golang.org>
Diffstat (limited to 'misc')
-rw-r--r--misc/cgo/errors/argposition_test.go134
-rw-r--r--misc/cgo/errors/testdata/issue42580.go44
2 files changed, 178 insertions, 0 deletions
diff --git a/misc/cgo/errors/argposition_test.go b/misc/cgo/errors/argposition_test.go
new file mode 100644
index 0000000000..331095f747
--- /dev/null
+++ b/misc/cgo/errors/argposition_test.go
@@ -0,0 +1,134 @@
+// Copyright 2021 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.
+
+// Issue 42580: cmd/cgo: shifting identifier position in ast
+
+package errorstest
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+type ShortPosition struct {
+ Line int
+ Column int
+ Visited bool
+}
+
+type IdentPositionInfo map[string][]ShortPosition
+
+type Visitor struct {
+ identPosInfo IdentPositionInfo
+ fset *token.FileSet
+ t *testing.T
+}
+
+func (v *Visitor) Visit(node ast.Node) ast.Visitor {
+ if ident, ok := node.(*ast.Ident); ok {
+ if expectedPositions, ok := v.identPosInfo[ident.Name]; ok {
+ gotMatch := false
+ var errorMessage strings.Builder
+ for caseIndex, expectedPos := range expectedPositions {
+ actualPosition := v.fset.PositionFor(ident.Pos(), true)
+ errorOccured := false
+ if expectedPos.Line != actualPosition.Line {
+ fmt.Fprintf(&errorMessage, "wrong line number for ident %s: expected: %d got: %d\n", ident.Name, expectedPos.Line, actualPosition.Line)
+ errorOccured = true
+ }
+ if expectedPos.Column != actualPosition.Column {
+ fmt.Fprintf(&errorMessage, "wrong column number for ident %s: expected: %d got: %d\n", ident.Name, expectedPos.Column, actualPosition.Column)
+ errorOccured = true
+ }
+ if errorOccured {
+ continue
+ }
+ gotMatch = true
+ expectedPositions[caseIndex].Visited = true
+ }
+
+ if !gotMatch {
+ v.t.Errorf(errorMessage.String())
+ }
+ }
+ }
+ return v
+}
+
+func TestArgumentsPositions(t *testing.T) {
+ testdata, err := filepath.Abs("testdata")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ tmpPath := t.TempDir()
+
+ dir := filepath.Join(tmpPath, "src", "testpositions")
+ if err := os.MkdirAll(dir, 0755); err != nil {
+ t.Fatal(err)
+ }
+
+ cmd := exec.Command("go", "tool", "cgo",
+ "-srcdir", testdata,
+ "-objdir", dir,
+ "issue42580.go")
+ cmd.Stderr = new(bytes.Buffer)
+
+ err = cmd.Run()
+ if err != nil {
+ t.Fatalf("%s: %v\n%s", cmd, err, cmd.Stderr)
+ }
+ mainProcessed, err := ioutil.ReadFile(filepath.Join(dir, "issue42580.cgo1.go"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, "", mainProcessed, parser.AllErrors)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+
+ expectation := IdentPositionInfo{
+ "checkedPointer": []ShortPosition{
+ ShortPosition{
+ Line: 32,
+ Column: 56,
+ },
+ },
+ "singleInnerPointerChecked": []ShortPosition{
+ ShortPosition{
+ Line: 37,
+ Column: 91,
+ },
+ },
+ "doublePointerChecked": []ShortPosition{
+ ShortPosition{
+ Line: 42,
+ Column: 91,
+ },
+ },
+ }
+ for _, decl := range f.Decls {
+ if fdecl, ok := decl.(*ast.FuncDecl); ok {
+ ast.Walk(&Visitor{expectation, fset, t}, fdecl.Body)
+ }
+ }
+ for ident, positions := range expectation {
+ for _, position := range positions {
+ if !position.Visited {
+ t.Errorf("Position %d:%d missed for %s ident", position.Line, position.Column, ident)
+ }
+ }
+ }
+}
diff --git a/misc/cgo/errors/testdata/issue42580.go b/misc/cgo/errors/testdata/issue42580.go
new file mode 100644
index 0000000000..aba80dfeba
--- /dev/null
+++ b/misc/cgo/errors/testdata/issue42580.go
@@ -0,0 +1,44 @@
+// Copyright 2021 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.
+
+// Issue 42580: cmd/cgo: shifting identifier position in ast
+
+package cgotest
+
+// typedef int (*intFunc) ();
+//
+// char* strarg = "";
+//
+// int func_with_char(char* arg, void* dummy)
+// {return 5;}
+//
+// int* get_arr(char* arg, void* dummy)
+// {return NULL;}
+import "C"
+import "unsafe"
+
+// Test variables
+var (
+ checkedPointer = []byte{1}
+ doublePointerChecked = []byte{1}
+ singleInnerPointerChecked = []byte{1}
+)
+
+// This test checks the positions of variable identifiers.
+// Changing the positions of the test variables idents after this point will break the test.
+
+func TestSingleArgumentCast() C.int {
+ retcode := C.func_with_char((*C.char)(unsafe.Pointer(&checkedPointer[0])), unsafe.Pointer(C.strarg))
+ return retcode
+}
+
+func TestSingleArgumentCastRecFuncAsSimpleArg() C.int {
+ retcode := C.func_with_char((*C.char)(unsafe.Pointer(C.get_arr((*C.char)(unsafe.Pointer(&singleInnerPointerChecked[0])), unsafe.Pointer(C.strarg)))), nil)
+ return retcode
+}
+
+func TestSingleArgumentCastRecFunc() C.int {
+ retcode := C.func_with_char((*C.char)(unsafe.Pointer(C.get_arr((*C.char)(unsafe.Pointer(&doublePointerChecked[0])), unsafe.Pointer(C.strarg)))), unsafe.Pointer(C.strarg))
+ return retcode
+}