mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/cgo: accept expressions as untyped constants
Fixes #28545 Change-Id: I31c57ce11aca651cacc72235c7753e0c0fd170ef Reviewed-on: https://go-review.googlesource.com/c/146900 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
This commit is contained in:
parent
745ec8b922
commit
4d567310d2
2 changed files with 38 additions and 1 deletions
20
misc/cgo/test/issue28545.go
Normal file
20
misc/cgo/test/issue28545.go
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// Failed to add type conversion for negative constant.
|
||||||
|
// No runtime test; just make sure it compiles.
|
||||||
|
|
||||||
|
package cgotest
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <complex.h>
|
||||||
|
|
||||||
|
static void issue28545F(char **p, int n, complex double a) {}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func issue28545G(p **C.char) {
|
||||||
|
C.issue28545F(p, -1, (0))
|
||||||
|
C.issue28545F(p, 2+3, complex(1, 1))
|
||||||
|
}
|
||||||
|
|
@ -1214,7 +1214,7 @@ func (p *Package) isType(t ast.Expr) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// isConst returns whether x is an untyped constant.
|
// isConst returns whether x is an untyped constant expression.
|
||||||
func (p *Package) isConst(f *File, x ast.Expr) bool {
|
func (p *Package) isConst(f *File, x ast.Expr) bool {
|
||||||
switch x := x.(type) {
|
switch x := x.(type) {
|
||||||
case *ast.BasicLit:
|
case *ast.BasicLit:
|
||||||
|
|
@ -1233,6 +1233,23 @@ func (p *Package) isConst(f *File, x ast.Expr) bool {
|
||||||
strings.HasPrefix(x.Name, "_Ciconst_") ||
|
strings.HasPrefix(x.Name, "_Ciconst_") ||
|
||||||
strings.HasPrefix(x.Name, "_Cfconst_") ||
|
strings.HasPrefix(x.Name, "_Cfconst_") ||
|
||||||
strings.HasPrefix(x.Name, "_Csconst_")
|
strings.HasPrefix(x.Name, "_Csconst_")
|
||||||
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue