--- /dev/null
+// Copyright 2019 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.
+
+package issue30527
+
+import "math"
+
+/*
+#include <inttypes.h>
+
+static void issue30527F(char **p, uint64_t mod, uint32_t unused) {}
+*/
+import "C"
+
+func G(p **C.char) {
+ C.issue30527F(p, math.MaxUint64, 1)
+ C.issue30527F(p, 1<<64-1, Z)
+}
needsUnsafe = true
}
- // Explicitly convert untyped constants to the
- // parameter type, to avoid a type mismatch.
- if p.isConst(f, arg) {
- ptype := p.rewriteUnsafe(param.Go)
+ // Use "var x T = ..." syntax to explicitly convert untyped
+ // constants to the parameter type, to avoid a type mismatch.
+ ptype := p.rewriteUnsafe(param.Go)
+
+ if !p.needsPointerCheck(f, param.Go, args[i]) {
if ptype != param.Go {
needsUnsafe = true
}
- arg = &ast.CallExpr{
- Fun: ptype,
- Args: []ast.Expr{arg},
- }
- }
-
- if !p.needsPointerCheck(f, param.Go, args[i]) {
- fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
+ fmt.Fprintf(&sb, "var _cgo%d %s = %s; ", i,
+ gofmtLine(ptype), gofmtPos(arg, origArg.Pos()))
continue
}
return false
}
-// isConst reports whether x is an untyped constant expression.
-func (p *Package) isConst(f *File, x ast.Expr) bool {
- switch x := x.(type) {
- case *ast.BasicLit:
- return true
- case *ast.SelectorExpr:
- id, ok := x.X.(*ast.Ident)
- if !ok || id.Name != "C" {
- return false
- }
- name := f.Name[x.Sel.Name]
- if name != nil {
- return name.IsConst()
- }
- case *ast.Ident:
- return x.Name == "nil" ||
- strings.HasPrefix(x.Name, "_Ciconst_") ||
- strings.HasPrefix(x.Name, "_Cfconst_") ||
- strings.HasPrefix(x.Name, "_Csconst_") ||
- consts[x.Name]
- case *ast.UnaryExpr:
- return p.isConst(f, x.X)
- case *ast.BinaryExpr:
- return p.isConst(f, x.X) && p.isConst(f, x.Y)
- case *ast.ParenExpr:
- return p.isConst(f, x.X)
- case *ast.CallExpr:
- // Calling the builtin function complex on two untyped
- // constants returns an untyped constant.
- // TODO: It's possible to construct a case that will
- // erroneously succeed if there is a local function
- // named "complex", shadowing the builtin, that returns
- // a numeric type. I can't think of any cases that will
- // erroneously fail.
- if id, ok := x.Fun.(*ast.Ident); ok && id.Name == "complex" && len(x.Args) == 2 {
- return p.isConst(f, x.Args[0]) && p.isConst(f, x.Args[1])
- }
- }
- return false
-}
-
// isVariable reports whether x is a variable, possibly with field references.
func (p *Package) isVariable(x ast.Expr) bool {
switch x := x.(type) {