From 76e8ca447c6d48cadf4c355112e5c6bd60b9a2e8 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 15 Jan 2019 07:46:39 -0800 Subject: [PATCH] cmd/cgo: don't replace newlines with semicolons in composite literals Fixes #29748 Change-Id: I2b19165bdb3c99df5b79574390b5d5f6d40462dc Reviewed-on: https://go-review.googlesource.com/c/157961 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- misc/cgo/test/issue29748.go | 22 ++++++++++++++++++++++ src/cmd/cgo/godefs.go | 15 ++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 misc/cgo/test/issue29748.go diff --git a/misc/cgo/test/issue29748.go b/misc/cgo/test/issue29748.go new file mode 100644 index 0000000000..8229b3bcf0 --- /dev/null +++ b/misc/cgo/test/issue29748.go @@ -0,0 +1,22 @@ +// 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. + +// Error handling a struct initializer that requires pointer checking. +// Compilation test only, nothing to run. + +package cgotest + +// typedef struct { char **p; } S29748; +// static int f29748(S29748 *p) { return 0; } +import "C" + +var Vissue29748 = C.f29748(&C.S29748{ + nil, +}) + +func Fissue299748() { + C.f29748(&C.S29748{ + nil, + }) +} diff --git a/src/cmd/cgo/godefs.go b/src/cmd/cgo/godefs.go index 9c763a22fb..c0cd8e002f 100644 --- a/src/cmd/cgo/godefs.go +++ b/src/cmd/cgo/godefs.go @@ -127,8 +127,21 @@ func gofmt(n interface{}) string { return gofmtBuf.String() } +// gofmtLineReplacer is used to put a gofmt-formatted string for an +// AST expression onto a single line. The lexer normally inserts a +// semicolon at each newline, so we can replace newline with semicolon. +// However, we can't do that in cases where the lexer would not insert +// a semicolon. Fortunately we only have to worry about cases that +// can occur in an expression passed through gofmt, which just means +// composite literals. +var gofmtLineReplacer = strings.NewReplacer( + "{\n", "{", + ",\n", ",", + "\n", ";", +) + // gofmtLine returns the gofmt-formatted string for an AST node, // ensuring that it is on a single line. func gofmtLine(n interface{}) string { - return strings.Replace(gofmt(n), "\n", ";", -1) + return gofmtLineReplacer.Replace(gofmt(n)) } -- 2.50.0