]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: fix cgo checking when fetching errno value
authorIan Lance Taylor <iant@golang.org>
Wed, 30 Nov 2016 23:46:37 +0000 (15:46 -0800)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 1 Dec 2016 02:13:50 +0000 (02:13 +0000)
Fixes #18126.

Change-Id: I7ae090945ef203673b06eb94817cc5c894b5eadc
Reviewed-on: https://go-review.googlesource.com/33752
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
misc/cgo/test/cgo_test.go
misc/cgo/test/issue18126.go [new file with mode: 0644]
src/cmd/cgo/gcc.go

index 2f591377aee87755cd59dc0e73e60df49afa4b21..a6de999752b4ff0d6cf14da4ff5caf0f5e61b55c 100644 (file)
@@ -75,5 +75,6 @@ func Test17065(t *testing.T)                 { test17065(t) }
 func TestThreadLock(t *testing.T)            { testThreadLockFunc(t) }
 func TestCheckConst(t *testing.T)            { testCheckConst(t) }
 func Test17537(t *testing.T)                 { test17537(t) }
+func Test18126(t *testing.T)                 { test18126(t) }
 
 func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
diff --git a/misc/cgo/test/issue18126.go b/misc/cgo/test/issue18126.go
new file mode 100644 (file)
index 0000000..ac94a66
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2016 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 18126: cgo check of void function returning errno.
+
+package cgotest
+
+/*
+#include <stdlib.h>
+
+void Issue18126C(void **p) {
+}
+*/
+import "C"
+
+import (
+       "testing"
+)
+
+func test18126(t *testing.T) {
+       p := C.malloc(1)
+       _, err := C.Issue18126C(&p)
+       C.free(p)
+       _ = err
+}
index f6ddfbeceb3fcdec81dd253cbe00b04ecec59364..670a73f546c98ef9d2d7fc22bc27fc2fe119107c 100644 (file)
@@ -713,15 +713,7 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
                        List: params,
                },
        }
-       var fbody ast.Stmt
-       if name.FuncType.Result == nil {
-               fbody = &ast.ExprStmt{
-                       X: fcall,
-               }
-       } else {
-               fbody = &ast.ReturnStmt{
-                       Results: []ast.Expr{fcall},
-               }
+       if name.FuncType.Result != nil {
                rtype := p.rewriteUnsafe(name.FuncType.Result.Go)
                if rtype != name.FuncType.Result.Go {
                        needsUnsafe = true
@@ -734,14 +726,6 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
                        },
                }
        }
-       call.Call.Fun = &ast.FuncLit{
-               Type: ftype,
-               Body: &ast.BlockStmt{
-                       List: append(stmts, fbody),
-               },
-       }
-       call.Call.Lparen = token.NoPos
-       call.Call.Rparen = token.NoPos
 
        // There is a Ref pointing to the old call.Call.Fun.
        for _, ref := range f.Ref {
@@ -749,8 +733,20 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
                        ref.Expr = &fcall.Fun
 
                        // If this call expects two results, we have to
-                       // adjust the results of the  function we generated.
+                       // adjust the results of the function we generated.
                        if ref.Context == "call2" {
+                               if ftype.Results == nil {
+                                       // An explicit void argument
+                                       // looks odd but it seems to
+                                       // be how cgo has worked historically.
+                                       ftype.Results = &ast.FieldList{
+                                               List: []*ast.Field{
+                                                       &ast.Field{
+                                                               Type: ast.NewIdent("_Ctype_void"),
+                                                       },
+                                               },
+                                       }
+                               }
                                ftype.Results.List = append(ftype.Results.List,
                                        &ast.Field{
                                                Type: ast.NewIdent("error"),
@@ -759,6 +755,25 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
                }
        }
 
+       var fbody ast.Stmt
+       if ftype.Results == nil {
+               fbody = &ast.ExprStmt{
+                       X: fcall,
+               }
+       } else {
+               fbody = &ast.ReturnStmt{
+                       Results: []ast.Expr{fcall},
+               }
+       }
+       call.Call.Fun = &ast.FuncLit{
+               Type: ftype,
+               Body: &ast.BlockStmt{
+                       List: append(stmts, fbody),
+               },
+       }
+       call.Call.Lparen = token.NoPos
+       call.Call.Rparen = token.NoPos
+
        return needsUnsafe
 }