Skip to content

Commit 0993369

Browse files
hirochachachabroady
authored andcommitted
[release-branch.go1.9] cmd/cgo: support large unsigned macro again
The approach of https://golang.org/cl/43476 turned out incorrect. The problem is that the sniff introduced by the CL only work for simple expression. And when it fails it fallback to uint64, not int64, which breaks backward compatibility. In this CL, we use DWARF for guessing kind instead. That should be more reliable than previous approach. And importanly, it fallbacks to int64 even if it fails to guess kind. Fixes #21708 Change-Id: I39a18cb2efbe4faa9becdcf53d5ac68dba180d46 Reviewed-on: https://go-review.googlesource.com/60510 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-on: https://go-review.googlesource.com/60810 Reviewed-by: Hiroshi Ioka <[email protected]> Reviewed-by: Chris Broadfoot <[email protected]>
1 parent 7b4decc commit 0993369

File tree

4 files changed

+29
-31
lines changed

4 files changed

+29
-31
lines changed

misc/cgo/test/cgo_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,6 @@ func Test20369(t *testing.T) { test20369(t) }
8080
func Test18720(t *testing.T) { test18720(t) }
8181
func Test20266(t *testing.T) { test20266(t) }
8282
func Test20129(t *testing.T) { test20129(t) }
83+
func Test21708(t *testing.T) { test21708(t) }
8384

8485
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }

misc/cgo/test/issue21708.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2017 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package cgotest
6+
7+
// #include <stdint.h>
8+
// #define CAST_TO_INT64 (int64_t)(-1)
9+
import "C"
10+
import "testing"
11+
12+
func test21708(t *testing.T) {
13+
if got, want := C.CAST_TO_INT64, -1; got != want {
14+
t.Errorf("C.CAST_TO_INT64 == %v, expected %v", got, want)
15+
}
16+
}

src/cmd/cgo/gcc.go

+10-29
Original file line numberDiff line numberDiff line change
@@ -305,18 +305,12 @@ func (p *Package) guessKinds(f *File) []*Name {
305305
// void __cgo_f_xxx_4(void) { static const double __cgo_undefined__4 = (name); }
306306
// #line xxx "not-str-lit"
307307
// void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); }
308-
// #line xxx "not-signed-int-const"
309-
// #if 0 < -(name)
310-
// #line xxx "not-signed-int-const"
311-
// #error found unsigned int
312-
// #endif
313308
//
314309
// If we see an error at not-declared:xxx, the corresponding name is not declared.
315310
// If we see an error at not-type:xxx, the corresponding name is a type.
316311
// If we see an error at not-int-const:xxx, the corresponding name is not an integer constant.
317312
// If we see an error at not-num-const:xxx, the corresponding name is not a number constant.
318313
// If we see an error at not-str-lit:xxx, the corresponding name is not a string literal.
319-
// If we see an error at not-signed-int-const:xxx, the corresponding name is not a signed integer literal.
320314
//
321315
// The specific input forms are chosen so that they are valid C syntax regardless of
322316
// whether name denotes a type or an expression.
@@ -335,18 +329,12 @@ func (p *Package) guessKinds(f *File) []*Name {
335329
"#line %d \"not-num-const\"\n"+
336330
"void __cgo_f_%d_4(void) { static const double __cgo_undefined__4 = (%s); }\n"+
337331
"#line %d \"not-str-lit\"\n"+
338-
"void __cgo_f_%d_5(void) { static const char __cgo_undefined__5[] = (%s); }\n"+
339-
"#line %d \"not-signed-int-const\"\n"+
340-
"#if 0 < (%s)\n"+
341-
"#line %d \"not-signed-int-const\"\n"+
342-
"#error found unsigned int\n"+
343-
"#endif\n",
332+
"void __cgo_f_%d_5(void) { static const char __cgo_undefined__5[] = (%s); }\n",
344333
i+1, i+1, n.C,
345334
i+1, i+1, n.C,
346335
i+1, i+1, n.C,
347336
i+1, i+1, n.C,
348337
i+1, i+1, n.C,
349-
i+1, n.C, i+1,
350338
)
351339
}
352340
fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
@@ -365,7 +353,6 @@ func (p *Package) guessKinds(f *File) []*Name {
365353
notNumConst
366354
notStrLiteral
367355
notDeclared
368-
notSignedIntConst
369356
)
370357
sawUnmatchedErrors := false
371358
for _, line := range strings.Split(stderr, "\n") {
@@ -419,8 +406,6 @@ func (p *Package) guessKinds(f *File) []*Name {
419406
sniff[i] |= notNumConst
420407
case "not-str-lit":
421408
sniff[i] |= notStrLiteral
422-
case "not-signed-int-const":
423-
sniff[i] |= notSignedIntConst
424409
default:
425410
if isError {
426411
sawUnmatchedErrors = true
@@ -436,7 +421,7 @@ func (p *Package) guessKinds(f *File) []*Name {
436421
}
437422

438423
for i, n := range names {
439-
switch sniff[i] &^ notSignedIntConst {
424+
switch sniff[i] {
440425
default:
441426
var tpos token.Pos
442427
for _, ref := range f.Ref {
@@ -447,11 +432,7 @@ func (p *Package) guessKinds(f *File) []*Name {
447432
}
448433
error_(tpos, "could not determine kind of name for C.%s", fixGo(n.Go))
449434
case notStrLiteral | notType:
450-
if sniff[i]&notSignedIntConst != 0 {
451-
n.Kind = "uconst"
452-
} else {
453-
n.Kind = "iconst"
454-
}
435+
n.Kind = "iconst"
455436
case notIntConst | notStrLiteral | notType:
456437
n.Kind = "fconst"
457438
case notIntConst | notNumConst | notType:
@@ -496,7 +477,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
496477
b.WriteString("#line 1 \"cgo-dwarf-inference\"\n")
497478
for i, n := range names {
498479
fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i)
499-
if n.Kind == "iconst" || n.Kind == "uconst" {
480+
if n.Kind == "iconst" {
500481
fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C)
501482
}
502483
}
@@ -505,7 +486,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
505486
// so we can read them out of the object file.
506487
fmt.Fprintf(&b, "long long __cgodebug_ints[] = {\n")
507488
for _, n := range names {
508-
if n.Kind == "iconst" || n.Kind == "uconst" {
489+
if n.Kind == "iconst" {
509490
fmt.Fprintf(&b, "\t%s,\n", n.C)
510491
} else {
511492
fmt.Fprintf(&b, "\t0,\n")
@@ -614,11 +595,11 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
614595
switch n.Kind {
615596
case "iconst":
616597
if i < len(ints) {
617-
n.Const = fmt.Sprintf("%#x", ints[i])
618-
}
619-
case "uconst":
620-
if i < len(ints) {
621-
n.Const = fmt.Sprintf("%#x", uint64(ints[i]))
598+
if _, ok := types[i].(*dwarf.UintType); ok {
599+
n.Const = fmt.Sprintf("%#x", uint64(ints[i]))
600+
} else {
601+
n.Const = fmt.Sprintf("%#x", ints[i])
602+
}
622603
}
623604
case "fconst":
624605
if i < len(floats) {

src/cmd/cgo/main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ type Name struct {
8888
Mangle string // name used in generated Go
8989
C string // name used in C
9090
Define string // #define expansion
91-
Kind string // "iconst", "uconst", "fconst", "sconst", "type", "var", "fpvar", "func", "not-type"
91+
Kind string // "iconst", "fconst", "sconst", "type", "var", "fpvar", "func", "not-type"
9292
Type *Type // the type of xxx
9393
FuncType *FuncType
9494
AddError bool
@@ -100,7 +100,7 @@ func (n *Name) IsVar() bool {
100100
return n.Kind == "var" || n.Kind == "fpvar"
101101
}
102102

103-
// IsConst reports whether Kind is either "iconst", "uconst", "fconst" or "sconst"
103+
// IsConst reports whether Kind is either "iconst", "fconst" or "sconst"
104104
func (n *Name) IsConst() bool {
105105
return strings.HasSuffix(n.Kind, "const")
106106
}

0 commit comments

Comments
 (0)