]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: don't replace newlines with semicolons in composite literals
authorIan Lance Taylor <iant@golang.org>
Tue, 15 Jan 2019 15:46:39 +0000 (07:46 -0800)
committerIan Lance Taylor <iant@golang.org>
Tue, 15 Jan 2019 18:14:54 +0000 (18:14 +0000)
Fixes #29748

Change-Id: I2b19165bdb3c99df5b79574390b5d5f6d40462dc
Reviewed-on: https://go-review.googlesource.com/c/157961
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
misc/cgo/test/issue29748.go [new file with mode: 0644]
src/cmd/cgo/godefs.go

diff --git a/misc/cgo/test/issue29748.go b/misc/cgo/test/issue29748.go
new file mode 100644 (file)
index 0000000..8229b3b
--- /dev/null
@@ -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,
+       })
+}
index 9c763a22fb01c23318b479f0f48330aa539cba3f..c0cd8e002fea4d89e60c848e5edfb04a0d55d72e 100644 (file)
@@ -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))
 }