Commit dcaac4b3 authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/cgo: match note following error in compiler errors

With current GCC a macro that refers to another macro can report an
error on the macro definition line, with a note on the use.
When cgo is trying to decide which line an error refers to,
it is looking at the uses. So if we see an error on a line that we
don't recognize followed by a note on a line that we do recognize,
treat the note as an error.

Fixes #20125.

Change-Id: I389cd0eb7d56ad2d54bef70e278d9f76c4d36448
Reviewed-on: https://go-review.googlesource.com/44290
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: default avatarHiroshi Ioka <hirochachacha@gmail.com>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 491ec4df
...@@ -8,6 +8,10 @@ package cgotest ...@@ -8,6 +8,10 @@ package cgotest
#define HELLO "hello" #define HELLO "hello"
#define WORLD "world" #define WORLD "world"
#define HELLO_WORLD HELLO "\000" WORLD #define HELLO_WORLD HELLO "\000" WORLD
struct foo { char c; };
#define SIZE_OF(x) sizeof(x)
#define SIZE_OF_FOO SIZE_OF(struct foo)
*/ */
import "C" import "C"
import "testing" import "testing"
...@@ -16,4 +20,9 @@ func test18720(t *testing.T) { ...@@ -16,4 +20,9 @@ func test18720(t *testing.T) {
if C.HELLO_WORLD != "hello\000world" { if C.HELLO_WORLD != "hello\000world" {
t.Fatalf(`expected "hello\000world", but got %q`, C.HELLO_WORLD) t.Fatalf(`expected "hello\000world", but got %q`, C.HELLO_WORLD)
} }
// Issue 20125.
if got, want := C.SIZE_OF_FOO, 1; got != want {
t.Errorf("C.SIZE_OF_FOO == %v, expected %v", got, want)
}
} }
...@@ -367,10 +367,17 @@ func (p *Package) guessKinds(f *File) []*Name { ...@@ -367,10 +367,17 @@ func (p *Package) guessKinds(f *File) []*Name {
notDeclared notDeclared
notSignedIntConst notSignedIntConst
) )
sawUnmatchedErrors := false
for _, line := range strings.Split(stderr, "\n") { for _, line := range strings.Split(stderr, "\n") {
if !strings.Contains(line, ": error:") { // Ignore warnings and random comments, with one
// we only care about errors. // exception: newer GCC versions will sometimes emit
// we tried to turn off warnings on the command line, but one never knows. // an error on a macro #define with a note referring
// to where the expansion occurs. We care about where
// the expansion occurs, so in that case treat the note
// as an error.
isError := strings.Contains(line, ": error:")
isErrorNote := strings.Contains(line, ": note:") && sawUnmatchedErrors
if !isError && !isErrorNote {
continue continue
} }
...@@ -388,6 +395,9 @@ func (p *Package) guessKinds(f *File) []*Name { ...@@ -388,6 +395,9 @@ func (p *Package) guessKinds(f *File) []*Name {
i, _ := strconv.Atoi(line[c1+1 : c2]) i, _ := strconv.Atoi(line[c1+1 : c2])
i-- i--
if i < 0 || i >= len(names) { if i < 0 || i >= len(names) {
if isError {
sawUnmatchedErrors = true
}
continue continue
} }
...@@ -411,7 +421,14 @@ func (p *Package) guessKinds(f *File) []*Name { ...@@ -411,7 +421,14 @@ func (p *Package) guessKinds(f *File) []*Name {
sniff[i] |= notStrLiteral sniff[i] |= notStrLiteral
case "not-signed-int-const": case "not-signed-int-const":
sniff[i] |= notSignedIntConst sniff[i] |= notSignedIntConst
default:
if isError {
sawUnmatchedErrors = true
}
continue
} }
sawUnmatchedErrors = false
} }
if !completed { if !completed {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment