Commit fb8c896a authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/cgo: don't ignore qualifiers, don't cast to void*

The cgo tool used to simply ignore C type qualifiers. To avoid problems
when a C function expected a qualifier that was not present, cgo emitted
a cast to void* around all pointer arguments. Unfortunately, that broke
code that contains both a function declaration and a macro, when the
macro required the argument to have the right type. To fix this problem,
don't ignore qualifiers. They are easy enough to handle for the limited
set of cases that matter for cgo, in which we don't care about array or
function types.

Fixes #17537.

Change-Id: Ie2988d21db6ee016a3e99b07f53cfb0f1243a020
Reviewed-on: https://go-review.googlesource.com/33097
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent dc4a815d
......@@ -74,5 +74,6 @@ func Test8756(t *testing.T) { test8756(t) }
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 BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
// 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 17537. The void* cast introduced by cgo to avoid problems
// with const/volatile qualifiers breaks C preprocessor macros that
// emulate functions.
package cgotest
/*
#include <stdlib.h>
typedef struct {
int i;
} S17537;
int I17537(S17537 *p);
#define I17537(p) ((p)->i)
// Calling this function used to fail without the cast.
int F17537(const char **p) {
return **p;
}
*/
import "C"
import "testing"
func test17537(t *testing.T) {
v := C.S17537{i: 17537}
if got, want := C.I17537(&v), C.int(17537); got != want {
t.Errorf("got %d, want %d", got, want)
}
p := (*C.char)(C.malloc(1))
*p = 17
if got, want := C.F17537(&p), C.int(17); got != want {
t.Errorf("got %d, want %d", got, want)
}
}
......@@ -1702,9 +1702,13 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t)
case *dwarf.QualType:
// Ignore qualifier.
t = c.Type(dt.Type, pos)
c.m[dtype] = t
t1 := c.Type(dt.Type, pos)
t.Size = t1.Size
t.Align = t1.Align
t.Go = t1.Go
t.EnumValues = nil
t.Typedef = ""
t.C.Set("%s "+dt.Qual, t1.C)
return t
case *dwarf.StructType:
......
......@@ -355,11 +355,7 @@ func (p *Package) structType(n *Name) (string, int64) {
fmt.Fprintf(&buf, "\t\tchar __pad%d[%d];\n", off, pad)
off += pad
}
qual := ""
if c := t.C.String(); c[len(c)-1] == '*' {
qual = "const "
}
fmt.Fprintf(&buf, "\t\t%s%s r;\n", qual, t.C)
fmt.Fprintf(&buf, "\t\t%s r;\n", t.C)
off += t.Size
}
if off%p.PtrSize != 0 {
......@@ -620,20 +616,10 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
}
}
fmt.Fprintf(fgcc, "%s(", n.C)
for i, t := range n.FuncType.Params {
for i := range n.FuncType.Params {
if i > 0 {
fmt.Fprintf(fgcc, ", ")
}
// We know the type params are correct, because
// the Go equivalents had good type params.
// However, our version of the type omits the magic
// words const and volatile, which can provoke
// C compiler warnings. Silence them by casting
// all pointers to void*. (Eventually that will produce
// other warnings.)
if c := t.C.String(); c[len(c)-1] == '*' {
fmt.Fprintf(fgcc, "(void*)")
}
fmt.Fprintf(fgcc, "a->p%d", i)
}
fmt.Fprintf(fgcc, ");\n")
......@@ -693,14 +679,10 @@ func (p *Package) writeGccgoOutputFunc(fgcc *os.File, n *Name) {
}
}
fmt.Fprintf(fgcc, "%s(", n.C)
for i, t := range n.FuncType.Params {
for i := range n.FuncType.Params {
if i > 0 {
fmt.Fprintf(fgcc, ", ")
}
// Cast to void* to avoid warnings due to omitted qualifiers.
if c := t.C.String(); c[len(c)-1] == '*' {
fmt.Fprintf(fgcc, "(void*)")
}
fmt.Fprintf(fgcc, "p%d", i)
}
fmt.Fprintf(fgcc, ");\n")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment