compiler: check for nil receiver in value method
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 1 Feb 2018 01:38:52 +0000 (01:38 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 1 Feb 2018 01:38:52 +0000 (01:38 +0000)
    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
gcc/go/gofrontend/gogo.cc
gcc/testsuite/go.go-torture/execute/printnil.go [new file with mode: 0644]

index c115b2e4f96cbb70d836731cee20c7ba98d4dd53..7dc00636527f2c6e2793c89bba9e795365846fc6 100644 (file)
@@ -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.
index 3f784dd80dc82a697cbbdf262c27d78950a5b2ea..04edb08c0314de14243dc8a3ce2291e77519d82b 100644 (file)
@@ -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 (file)
index 0000000..9b72dd4
--- /dev/null
@@ -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 != "<nil>" {
+               panic(got)
+       }
+}