From 22149e37f7537843947003b4c7df76b69dd287ac Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 1 Feb 2018 01:38:52 +0000 Subject: [PATCH] compiler: check for nil receiver in value method We already dereference the pointer to copy the value, but if the method does not use the value then the pointer dereference may be optimized away. Do an explicit nil check so that we get the panic that is required. Fixes golang/go#19806 Reviewed-on: https://go-review.googlesource.com/91275 * go.go-torture/execute/printnil.go: New test. From-SVN: r257280 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 2 +- .../go.go-torture/execute/printnil.go | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/go.go-torture/execute/printnil.go diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index c115b2e4f96..7dc00636527 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -65eaa9003db4effc9c5ffe9c955e9534ba5d7d15 +71758f9ca1804743afe178f0e2fca489e0217474 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 3f784dd80dc..04edb08c031 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -5610,7 +5610,7 @@ Function::build(Gogo* gogo, Named_object* named_function) Expression::make_var_reference(parm_no, loc); parm_ref = Expression::make_dereference(parm_ref, - Expression::NIL_CHECK_DEFAULT, + Expression::NIL_CHECK_NEEDED, loc); if ((*p)->var_value()->is_in_heap()) parm_ref = Expression::make_heap_expression(parm_ref, loc); diff --git a/gcc/testsuite/go.go-torture/execute/printnil.go b/gcc/testsuite/go.go-torture/execute/printnil.go new file mode 100644 index 00000000000..9b72dd47364 --- /dev/null +++ b/gcc/testsuite/go.go-torture/execute/printnil.go @@ -0,0 +1,19 @@ +// printnil checks that fmt correctly handles a nil pointer receiver +// for a value method at all optimization levels. +package main + +import "fmt" + +type MyType struct { + val int +} + +func (t MyType) String() string { + return "foobar" +} + +func main() { + if got := fmt.Sprintf("%s", (*MyType)(nil)); got != "" { + panic(got) + } +} -- 2.30.2