Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cgo aborts translation for unknown type pointers #126

Closed
gopherbot opened this issue Nov 13, 2009 · 6 comments
Closed

cgo aborts translation for unknown type pointers #126

gopherbot opened this issue Nov 13, 2009 · 6 comments

Comments

@gopherbot
Copy link
Contributor

by eden.li:

What steps will reproduce the problem?

$ cat > empty.go <<EOF
package main

/*
struct st_dne;
typedef struct st_dne dne;
typedef struct {
    dne *a;
} empty;
*/
import "C"

var a C.empty
EOF
$ cgo empty.go; echo $?
dwarf.Type dne reports unknown size.
2

What is the expected output? What do you see instead?

Some libraries (e.g. libmysql) define empty structs similar to the one
above.  cgo should translate these into void pointers instead of aborting.

What is your $GOOS?  $GOARCH?

darwin, 386

Which revision are you sync'ed to?  (hg log -l 1)

4018:bbc290c53f85 (Thu Nov 12 16:12:28 2009 -0800)

Please provide any additional information below.

This patch appears to fix the problem.

diff -r bbc290c53f85 src/cmd/cgo/gcc.go
--- a/src/cmd/cgo/gcc.go    Thu Nov 12 16:12:28 2009 -0800
+++ b/src/cmd/cgo/gcc.go    Thu Nov 12 17:13:47 2009 -0800
@@ -420,6 +420,13 @@
            break;
        }
 
+       // Translate unknown type pointers as unsafe.Pointer
+       if dt.Type.Size() < 0 {
+           t.Go = c.unsafePointer;
+           t.C = "void*";
+           break;
+       }
+
        gt := &ast.StarExpr{};
        t.Go = gt;  // publish before recursive call
        sub := c.Type(dt.Type);
@rsc
Copy link
Contributor

rsc commented Nov 13, 2009

Comment 1:

Status changed to Accepted.

@gopherbot
Copy link
Contributor Author

Comment 2 by akunokuroneko:

That seems a bit kludgy - the Size is coming back as 0 on the struct, not something
referencing it, and so making it a void pointer is actually technically wrong
(however, for most intents and purposes, it works until you attempt to dereference it).
My solution which needs to be better verified was to make it a 0 byte opaque object,
but what it needs to be really is a "Unknown size" opaque object, and checks need to
be made that it's never dereferenced through that unknown-size object, and that the
object is never copied inside of go code.

@gopherbot
Copy link
Contributor Author

Comment 3 by eden.li:

Agreed, cgo already renders some types using Opaque() which turns unknown types into
a byte array of fixed size.  Maybe we can just treat types with invalid byte sizes as
0-length byte arrays?  It seems Go wouldn't be able to copy the object if this is the
case.
Here's a patch which works for me for when consuming libmysql.
diff -r 1d9d926b1aa7 src/cmd/cgo/gcc.go
--- a/src/cmd/cgo/gcc.go    Thu Nov 12 23:38:48 2009 -0800
+++ b/src/cmd/cgo/gcc.go    Fri Nov 13 10:01:45 2009 -0800
@@ -315,11 +315,15 @@
    t.Size = dtype.Size();
    t.Align = -1;
    t.C = dtype.Common().Name;
+   c.m[dtype] = t;
+
    if t.Size < 0 {
-       fatal("dwarf.Type %s reports unknown size", dtype)
+       // Treat unsized types as [0]byte
+       t.Size = 0;
+       t.Go = c.Opaque(0);
+       return t;
    }
 
-   c.m[dtype] = t;
    switch dt := dtype.(type) {
    default:
        fatal("unexpected type: %s", dtype)

@rsc
Copy link
Contributor

rsc commented Nov 14, 2009

Comment 4:

Issue #161 has been merged into this issue.

@rsc
Copy link
Contributor

rsc commented Nov 17, 2009

Comment 5:

Owner changed to r...@golang.org.

@rsc
Copy link
Contributor

rsc commented Nov 20, 2009

Comment 6:

This issue was closed by revision b30f753.

Status changed to Fixed.

Merged into issue #-.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
@rsc rsc removed their assignment Jun 22, 2022
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants