public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Go patch committed: Update to current Go library
@ 2011-05-20  9:44 Ian Lance Taylor
  2011-05-20 14:18 ` Rainer Orth
  0 siblings, 1 reply; 15+ messages in thread
From: Ian Lance Taylor @ 2011-05-20  9:44 UTC (permalink / raw)
  To: gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 449 bytes --]

I have committed a patch to update libgo to the current version of the
Go library.  This patch includes some minor changes to the Go frontend
and to the testsuite.  The patch is too large to include here, but most
of it is simply a copy of the changes to the master Go library.  I have
appended the changes to the files which are not in the master library.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 67123 bytes --]

Index: gcc/go/gofrontend/types.h
===================================================================
--- gcc/go/gofrontend/types.h	(revision 173742)
+++ gcc/go/gofrontend/types.h	(working copy)
@@ -1044,7 +1044,7 @@ class Type
   // Build a composite literal for one method.
   Expression*
   method_constructor(Gogo*, Type* method_type, const std::string& name,
-		     const Method*) const;
+		     const Method*, bool only_value_methods) const;
 
   static tree
   build_receive_return_type(tree type);
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 173742)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -1432,7 +1432,7 @@ Type::methods_constructor(Gogo* gogo, Ty
        p != smethods.end();
        ++p)
     vals->push_back(this->method_constructor(gogo, method_type, p->first,
-					     p->second));
+					     p->second, only_value_methods));
 
   return Expression::make_slice_composite_literal(methods_type, vals, bloc);
 }
@@ -1444,7 +1444,8 @@ Type::methods_constructor(Gogo* gogo, Ty
 Expression*
 Type::method_constructor(Gogo*, Type* method_type,
 			 const std::string& method_name,
-			 const Method* m) const
+			 const Method* m,
+			 bool only_value_methods) const
 {
   source_location bloc = BUILTINS_LOCATION;
 
@@ -1487,6 +1488,25 @@ Type::method_constructor(Gogo*, Type* me
 
   ++p;
   go_assert(p->field_name() == "typ");
+  if (!only_value_methods && m->is_value_method())
+    {
+      // This is a value method on a pointer type.  Change the type of
+      // the method to use a pointer receiver.  The implementation
+      // always uses a pointer receiver anyhow.
+      Type* rtype = mtype->receiver()->type();
+      Type* prtype = Type::make_pointer_type(rtype);
+      Typed_identifier* receiver =
+	new Typed_identifier(mtype->receiver()->name(), prtype,
+			     mtype->receiver()->location());
+      mtype = Type::make_function_type(receiver,
+				       (mtype->parameters() == NULL
+					? NULL
+					: mtype->parameters()->copy()),
+				       (mtype->results() == NULL
+					? NULL
+					: mtype->results()->copy()),
+				       mtype->location());
+    }
   vals->push_back(Expression::make_type_descriptor(mtype, bloc));
 
   ++p;
@@ -2779,14 +2799,7 @@ Function_type::type_descriptor_params(Ty
 		+ (receiver != NULL ? 1 : 0));
 
   if (receiver != NULL)
-    {
-      Type* rtype = receiver->type();
-      // The receiver is always passed as a pointer.  FIXME: Is this
-      // right?  Should that fact affect the type descriptor?
-      if (rtype->points_to() == NULL)
-	rtype = Type::make_pointer_type(rtype);
-      vals->push_back(Expression::make_type_descriptor(rtype, bloc));
-    }
+    vals->push_back(Expression::make_type_descriptor(receiver->type(), bloc));
 
   if (params != NULL)
     {
@@ -4822,9 +4835,10 @@ Array_type::make_array_type_descriptor_t
       Type* uintptr_type = Type::lookup_integer_type("uintptr");
 
       Struct_type* sf =
-	Type::make_builtin_struct_type(3,
+	Type::make_builtin_struct_type(4,
 				       "", tdt,
 				       "elem", ptdt,
+				       "slice", ptdt,
 				       "len", uintptr_type);
 
       ret = Type::make_builtin_named_type("ArrayType", sf);
@@ -4891,6 +4905,11 @@ Array_type::array_type_descriptor(Gogo* 
   vals->push_back(Expression::make_type_descriptor(this->element_type_, bloc));
 
   ++p;
+  go_assert(p->field_name() == "slice");
+  Type* slice_type = Type::make_array_type(this->element_type_, NULL);
+  vals->push_back(Expression::make_type_descriptor(slice_type, bloc));
+
+  ++p;
   go_assert(p->field_name() == "len");
   vals->push_back(Expression::make_cast(p->type(), this->length_, bloc));
 
@@ -5375,8 +5394,9 @@ Channel_type::do_make_expression_tree(Tr
   Gogo* gogo = context->gogo();
   tree channel_type = type_to_tree(this->get_backend(gogo));
 
-  tree element_tree = type_to_tree(this->element_type_->get_backend(gogo));
-  tree element_size_tree = size_in_bytes(element_tree);
+  Type* ptdt = Type::make_type_descriptor_ptr_type();
+  tree element_type_descriptor =
+    this->element_type_->type_descriptor_pointer(gogo);
 
   tree bad_index = NULL_TREE;
 
@@ -5402,8 +5422,8 @@ Channel_type::do_make_expression_tree(Tr
 				"__go_new_channel",
 				2,
 				channel_type,
-				sizetype,
-				element_size_tree,
+				type_to_tree(ptdt->get_backend(gogo)),
+				element_type_descriptor,
 				sizetype,
 				expr_tree);
   if (ret == error_mark_node)
@@ -6242,7 +6262,16 @@ Interface_type::do_reflection(Gogo* gogo
 	  if (p != this->methods_->begin())
 	    ret->append(";");
 	  ret->push_back(' ');
-	  ret->append(Gogo::unpack_hidden_name(p->name()));
+	  if (!Gogo::is_hidden_name(p->name()))
+	    ret->append(p->name());
+	  else
+	    {
+	      // This matches what the gc compiler does.
+	      std::string prefix = Gogo::hidden_name_prefix(p->name());
+	      ret->append(prefix.substr(prefix.find('.') + 1));
+	      ret->push_back('.');
+	      ret->append(Gogo::unpack_hidden_name(p->name()));
+	    }
 	  std::string sub = p->type()->reflection(gogo);
 	  go_assert(sub.compare(0, 4, "func") == 0);
 	  sub = sub.substr(4);
Index: libgo/Makefile.am
===================================================================
--- libgo/Makefile.am	(revision 173685)
+++ libgo/Makefile.am	(working copy)
@@ -248,7 +248,8 @@ toolexeclibgogo_DATA = \
 	go/printer.gox \
 	go/scanner.gox \
 	go/token.gox \
-	go/typechecker.gox
+	go/typechecker.gox \
+	go/types.gox
 
 toolexeclibgohashdir = $(toolexeclibgodir)/hash
 
@@ -262,14 +263,19 @@ toolexeclibgohttpdir = $(toolexeclibgodi
 
 toolexeclibgohttp_DATA = \
 	http/cgi.gox \
+	http/fcgi.gox \
 	http/httptest.gox \
-	http/pprof.gox
+	http/pprof.gox \
+	http/spdy.gox
 
 toolexeclibgoimagedir = $(toolexeclibgodir)/image
 
 toolexeclibgoimage_DATA = \
+	image/gif.gox \
 	image/jpeg.gox \
-	image/png.gox
+	image/png.gox \
+	image/tiff.gox \
+	image/ycbcr.gox
 
 toolexeclibgoindexdir = $(toolexeclibgodir)/index
 
@@ -303,6 +309,7 @@ endif
 
 toolexeclibgoos_DATA = \
 	$(os_inotify_gox) \
+	os/user.gox \
 	os/signal.gox
 
 toolexeclibgopathdir = $(toolexeclibgodir)/path
@@ -404,6 +411,7 @@ runtime_files = \
 	runtime/go-send-nb-big.c \
 	runtime/go-send-nb-small.c \
 	runtime/go-send-small.c \
+	runtime/go-setenv.c \
 	runtime/go-signal.c \
 	runtime/go-strcmp.c \
 	runtime/go-string-to-byte-array.c \
@@ -560,6 +568,7 @@ go_http_files = \
 	go/http/persist.go \
 	go/http/request.go \
 	go/http/response.go \
+	go/http/reverseproxy.go \
 	go/http/server.go \
 	go/http/status.go \
 	go/http/transfer.go \
@@ -656,8 +665,17 @@ go_net_newpollserver_file = go/net/newpo
 endif # !LIBGO_IS_LINUX
 endif # !LIBGO_IS_RTEMS
 
+if LIBGO_IS_LINUX
+go_net_cgo_file = go/net/cgo_linux.go
+go_net_sock_file = go/net/sock_linux.go
+else
+go_net_cgo_file = go/net/cgo_bsd.go
+go_net_sock_file = go/net/sock_bsd.go
+endif
+
 go_net_files = \
-	go/net/cgo_stub.go \
+	go/net/cgo_unix.go \
+	$(go_net_cgo_file) \
 	go/net/dial.go \
 	go/net/dnsclient.go \
 	go/net/dnsconfig.go \
@@ -676,6 +694,7 @@ go_net_files = \
 	go/net/pipe.go \
 	go/net/port.go \
 	go/net/sock.go \
+	$(go_net_sock_file) \
 	go/net/tcpsock.go \
 	go/net/udpsock.go \
 	go/net/unixsock.go
@@ -1002,7 +1021,6 @@ go_crypto_subtle_files = \
 	go/crypto/subtle/constant_time.go
 go_crypto_tls_files = \
 	go/crypto/tls/alert.go \
-	go/crypto/tls/ca_set.go \
 	go/crypto/tls/cipher_suites.go \
 	go/crypto/tls/common.go \
 	go/crypto/tls/conn.go \
@@ -1015,6 +1033,8 @@ go_crypto_tls_files = \
 go_crypto_twofish_files = \
 	go/crypto/twofish/twofish.go
 go_crypto_x509_files = \
+	go/crypto/x509/cert_pool.go \
+	go/crypto/x509/verify.go \
 	go/crypto/x509/x509.go
 go_crypto_xtea_files = \
 	go/crypto/xtea/block.go \
@@ -1130,6 +1150,12 @@ go_go_typechecker_files = \
 	go/go/typechecker/type.go \
 	go/go/typechecker/typechecker.go \
 	go/go/typechecker/universe.go
+go_go_types_files = \
+	go/go/types/const.go \
+	go/go/types/exportdata.go \
+	go/go/types/gcimporter.go \
+	go/go/types/types.go \
+	go/go/types/universe.go
 
 go_hash_adler32_files = \
 	go/hash/adler32/adler32.go
@@ -1143,21 +1169,39 @@ go_hash_fnv_files = \
 go_http_cgi_files = \
 	go/http/cgi/child.go \
 	go/http/cgi/host.go
+go_http_fcgi_files = \
+	go/http/fcgi/child.go \
+	go/http/fcgi/fcgi.go
 go_http_httptest_files = \
 	go/http/httptest/recorder.go \
 	go/http/httptest/server.go
 go_http_pprof_files = \
 	go/http/pprof/pprof.go
+go_http_spdy_files = \
+	go/http/spdy/protocol.go
+
+go_image_gif_files = \
+	go/image/gif/reader.go
 
 go_image_jpeg_files = \
+	go/image/jpeg/fdct.go \
 	go/image/jpeg/huffman.go \
 	go/image/jpeg/idct.go \
-	go/image/jpeg/reader.go
+	go/image/jpeg/reader.go \
+	go/image/jpeg/writer.go
 
 go_image_png_files = \
 	go/image/png/reader.go \
 	go/image/png/writer.go
 
+go_image_tiff_files = \
+	go/image/tiff/buffer.go \
+	go/image/tiff/consts.go \
+	go/image/tiff/reader.go
+
+go_image_ycbcr_files = \
+	go/image/ycbcr/ycbcr.go
+
 go_index_suffixarray_files = \
 	go/index/suffixarray/qsufsort.go \
 	go/index/suffixarray/suffixarray.go
@@ -1167,6 +1211,7 @@ go_io_ioutil_files = \
 	go/io/ioutil/tempfile.go
 
 go_mime_multipart_files = \
+	go/mime/multipart/formdata.go \
 	go/mime/multipart/multipart.go
 
 go_net_dict_files = \
@@ -1182,6 +1227,10 @@ go_net_textproto_files = \
 go_os_inotify_files = \
 	go/os/inotify/inotify_linux.go
 
+go_os_user_files = \
+	go/os/user/user.go \
+	go/os/user/lookup_unix.go
+
 go_os_signal_files = \
 	go/os/signal/signal.go \
 	unix.go
@@ -1485,21 +1534,28 @@ libgo_go_objs = \
 	go/scanner.lo \
 	go/token.lo \
 	go/typechecker.lo \
+	go/types.lo \
 	hash/adler32.lo \
 	hash/crc32.lo \
 	hash/crc64.lo \
 	hash/fnv.lo \
 	http/cgi.lo \
+	http/fcgi.lo \
 	http/httptest.lo \
 	http/pprof.lo \
+	http/spdy.lo \
+	image/gif.lo \
 	image/jpeg.lo \
 	image/png.lo \
+	image/tiff.lo \
+	image/ycbcr.lo \
 	index/suffixarray.lo \
 	io/ioutil.lo \
 	mime/multipart.lo \
 	net/dict.lo \
 	net/textproto.lo \
 	$(os_lib_inotify_lo) \
+	os/user.lo \
 	os/signal.lo \
 	path/filepath.lo \
 	rpc/jsonrpc.lo \
@@ -1711,11 +1767,12 @@ html/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: html/check
 
-http/http.lo: $(go_http_files) bufio.gox bytes.gox container/vector.gox \
-		crypto/rand.gox crypto/tls.gox encoding/base64.gox fmt.gox \
-		io.gox io/ioutil.gox log.gox mime.gox mime/multipart.gox \
-		net.gox net/textproto.gox os.gox path.gox path/filepath.gox \
-		sort.gox strconv.gox strings.gox sync.gox time.gox utf8.gox
+http/http.lo: $(go_http_files) bufio.gox bytes.gox compress/gzip.gox \
+		container/vector.gox crypto/rand.gox crypto/tls.gox \
+		encoding/base64.gox fmt.gox io.gox io/ioutil.gox log.gox \
+		mime.gox mime/multipart.gox net.gox net/textproto.gox os.gox \
+		path.gox path/filepath.gox sort.gox strconv.gox strings.gox \
+		sync.gox time.gox utf8.gox
 	$(BUILDPACKAGE)
 http/check: $(CHECK_DEPS)
 	@$(CHECK)
@@ -1755,7 +1812,7 @@ math/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: math/check
 
-mime/mime.lo: $(go_mime_files) bufio.gox bytes.gox os.gox strings.gox \
+mime/mime.lo: $(go_mime_files) bufio.gox bytes.gox fmt.gox os.gox strings.gox \
 		sync.gox unicode.gox
 	$(BUILDPACKAGE)
 mime/check: $(CHECK_DEPS)
@@ -1763,8 +1820,8 @@ mime/check: $(CHECK_DEPS)
 .PHONY: mime/check
 
 net/net.lo: $(go_net_files) bytes.gox fmt.gox io.gox os.gox rand.gox \
-		reflect.gox strconv.gox strings.gox sync.gox syscall.gox \
-		time.gox
+		reflect.gox sort.gox strconv.gox strings.gox sync.gox \
+		syscall.gox time.gox
 	$(BUILDPACKAGE)
 net/check: $(CHECK_DEPS)
 	@$(CHECK_ON_REQUEST)
@@ -1945,8 +2002,8 @@ xml/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: xml/check
 
-archive/tar.lo: $(go_archive_tar_files) bytes.gox io.gox os.gox strconv.gox \
-		strings.gox
+archive/tar.lo: $(go_archive_tar_files) bytes.gox io.gox io/ioutil.gox os.gox \
+		strconv.gox strings.gox
 	$(BUILDPACKAGE)
 archive/tar/check: $(CHECK_DEPS)
 	@$(MKDIR_P) archive/tar
@@ -2148,8 +2205,7 @@ crypto/ripemd160/check: $(CHECK_DEPS)
 .PHONY: crypto/ripemd160/check
 
 crypto/rsa.lo: $(go_crypto_rsa_files) big.gox crypto.gox crypto/sha1.gox \
-		crypto/subtle.gox encoding/hex.gox hash.gox io.gox os.gox \
-		sync.gox
+		crypto/subtle.gox encoding/hex.gox hash.gox io.gox os.gox
 	$(BUILDPACKAGE)
 crypto/rsa/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/rsa
@@ -2184,13 +2240,13 @@ crypto/subtle/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: crypto/subtle/check
 
-crypto/tls.lo: $(go_crypto_tls_files) big.gox bufio.gox bytes.gox \
-		container/list.gox crypto.gox crypto/aes.gox crypto/cipher.gox \
-		crypto/elliptic.gox crypto/hmac.gox crypto/md5.gox \
-		crypto/rc4.gox crypto/rand.gox crypto/rsa.gox crypto/sha1.gox \
-		crypto/subtle.gox crypto/rsa.gox crypto/sha1.gox \
-		crypto/x509.gox encoding/pem.gox fmt.gox hash.gox io.gox \
-		io/ioutil.gox net.gox os.gox strings.gox sync.gox time.gox
+crypto/tls.lo: $(go_crypto_tls_files) big.gox bytes.gox crypto.gox \
+		crypto/aes.gox crypto/cipher.gox crypto/elliptic.gox \
+		crypto/hmac.gox crypto/md5.gox crypto/rand.gox crypto/rc4.gox \
+		crypto/rsa.gox crypto/sha1.gox crypto/subtle.gox \
+		crypto/x509.gox encoding/pem.gox hash.gox io.gox \
+		io/ioutil.gox net.gox os.gox strconv.gox strings.gox sync.gox \
+		time.gox
 	$(BUILDPACKAGE)
 crypto/tls/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/tls
@@ -2204,9 +2260,10 @@ crypto/twofish/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: crypto/twofish/check
 
-crypto/x509.lo: $(go_crypto_x509_files) asn1.gox big.gox container/vector.gox \
-		crypto.gox crypto/rsa.gox crypto/sha1.gox hash.gox os.gox \
-		strings.gox time.gox
+crypto/x509.lo: $(go_crypto_x509_files) asn1.gox big.gox bytes.gox \
+		container/vector.gox crypto.gox crypto/rsa.gox \
+		crypto/sha1.gox encoding/pem.gox hash.gox os.gox strings.gox \
+		time.gox
 	$(BUILDPACKAGE)
 crypto/x509/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/x509
@@ -2220,9 +2277,8 @@ crypto/xtea/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: crypto/xtea/check
 
-crypto/openpgp/armor.lo: $(go_crypto_openpgp_armor_files) bytes.gox \
-		crypto/openpgp/error.gox encoding/base64.gox \
-		encoding/line.gox io.gox os.gox
+crypto/openpgp/armor.lo: $(go_crypto_openpgp_armor_files) bufio.gox bytes.gox \
+		crypto/openpgp/error.gox encoding/base64.gox io.gox os.gox
 	$(BUILDPACKAGE)
 crypto/openpgp/armor/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/openpgp/armor
@@ -2374,7 +2430,7 @@ exp/datafmt/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: exp/datafmt/check
 
-exp/draw.lo: $(go_exp_draw_files) image.gox os.gox
+exp/draw.lo: $(go_exp_draw_files) image.gox image/ycbcr.gox os.gox
 	$(BUILDPACKAGE)
 exp/draw/check: $(CHECK_DEPS)
 	@$(MKDIR_P) exp/draw
@@ -2448,6 +2504,15 @@ go/typechecker/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: go/typechecker/check
 
+go/types.lo: $(go_go_types_files) big.gox bufio.gox fmt.gox go/ast.gox \
+		go/token.gox io.gox os.gox path/filepath.gox runtime.gox \
+		scanner.gox strconv.gox strings.gox
+	$(BUILDPACKAGE)
+go/types/check: $(CHECK_DEPS)
+	@$(MKDIR_P) go/types
+	@$(CHECK)
+.PHONY: go/types/check
+
 hash/adler32.lo: $(go_hash_adler32_files) hash.gox os.gox
 	$(BUILDPACKAGE)
 hash/adler32/check: $(CHECK_DEPS)
@@ -2476,15 +2541,25 @@ hash/fnv/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: hash/fnv/check
 
-http/cgi.lo: $(go_http_cgi_files) bufio.gox bytes.gox encoding/line.gox \
-		exec.gox fmt.gox http.gox io.gox io/ioutil.gox log.gox \
-		os.gox path/filepath.gox regexp.gox strconv.gox strings.gox
+http/cgi.lo: $(go_http_cgi_files) bufio.gox bytes.gox crypto/tls.gox \
+		exec.gox fmt.gox http.gox net.gox io.gox io/ioutil.gox \
+		log.gox os.gox path/filepath.gox regexp.gox strconv.gox \
+		strings.gox
 	$(BUILDPACKAGE)
 http/cgi/check: $(CHECK_DEPS)
 	@$(MKDIR_P) http/cgi
 	@$(CHECK)
 .PHONY: http/cgi/check
 
+http/fcgi.lo: $(go_http_fcgi_files) bufio.gox bytes.gox encoding/binary.gox \
+		fmt.gox http.gox http/cgi.gox io.gox net.gox os.gox sync.gox \
+		time.gox
+	$(BUILDPACKAGE)
+http/fcgi/check: $(CHECK_DEPS)
+	@$(MKDIR_P) http/fcgi
+	@$(CHECK)
+.PHONY: http/fcgi/check
+
 http/httptest.lo: $(go_http_httptest_files) bytes.gox crypto/rand.gox \
 		crypto/tls.gox fmt.gox http.gox net.gox os.gox time.gox
 	$(BUILDPACKAGE)
@@ -2493,15 +2568,33 @@ http/httptest/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: http/httptest/check
 
-http/pprof.lo: $(go_http_pprof_files) bufio.gox fmt.gox http.gox os.gox \
-		runtime.gox runtime/pprof.gox strconv.gox strings.gox
+http/pprof.lo: $(go_http_pprof_files) bufio.gox bytes.gox fmt.gox http.gox \
+		os.gox runtime.gox runtime/pprof.gox strconv.gox strings.gox
 	$(BUILDPACKAGE)
 http/pprof/check: $(CHECK_DEPS)
 	@$(MKDIR_P) http/pprof
 	@$(CHECK)
 .PHONY: http/pprof/check
 
-image/jpeg.lo: $(go_image_jpeg_files) bufio.gox image.gox io.gox os.gox
+http/spdy.lo: $(go_http_spdy_files) bytes.gox compress/zlib.gox \
+		encoding/binary.gox http.gox io.gox os.gox strconv.gox \
+		strings.gox sync.gox
+	$(BUILDPACKAGE)
+http/spdy/check: $(CHECK_DEPS)
+	@$(MKDIR_P) http/spdy
+	@$(CHECK)
+.PHONY: http/spdy/check
+
+image/gif.lo: $(go_image_gif_files) bufio.gox compress/lzw.gox fmt.gox \
+		image.gox io.gox os.gox
+	$(BUILDPACKAGE)
+image/gif/check: $(CHECK_DEPS)
+	@$(MKDIR_P) image/gif
+	@$(CHECK)
+.PHONY: image/gif/check
+
+image/jpeg.lo: $(go_image_jpeg_files) bufio.gox image.gox image/ycbcr.gox \
+		io.gox os.gox
 	$(BUILDPACKAGE)
 image/jpeg/check: $(CHECK_DEPS)
 	@$(MKDIR_P) image/jpeg
@@ -2516,6 +2609,21 @@ image/png/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: image/png/check
 
+image/tiff.lo: $(go_image_tiff_files) compress/lzw.gox compress/zlib.gox \
+		encoding/binary.gox image.gox io.gox io/ioutil.gox os.gox
+	$(BUILDPACKAGE)
+image/tiff/check: $(CHECK_DEPS)
+	@$(MKDIR_P) image/tiff
+	@$(CHECK)
+.PHONY: image/tiff/check
+
+image/ycbcr.lo: $(go_image_ycbcr_files) image.gox
+	$(BUILDPACKAGE)
+image/ycbcr/check: $(CHECK_DEPS)
+	@$(MKDIR_P) image/ycbcr
+	@$(CHECK)
+.PHONY: image/ycbcr/check
+
 index/suffixarray.lo: $(go_index_suffixarray_files) bytes.gox regexp.gox \
 		sort.gox
 	$(BUILDPACKAGE)
@@ -2532,8 +2640,9 @@ io/ioutil/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: io/ioutil/check
 
-mime/multipart.lo: $(go_mime_multipart_files) bufio.gox bytes.gox io.gox \
-		mime.gox net/textproto.gox os.gox regexp.gox strings.gox
+mime/multipart.lo: $(go_mime_multipart_files) bufio.gox bytes.gox fmt.gox \
+		io.gox io/ioutil.gox mime.gox net/textproto.gox os.gox \
+		regexp.gox
 	$(BUILDPACKAGE)
 mime/multipart/check: $(CHECK_DEPS)
 	@$(MKDIR_P) mime/multipart
@@ -2560,6 +2669,14 @@ os/inotify/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: os/inotify/check
 
+os/user.lo: $(go_os_user_files) fmt.gox os.gox runtime.gox strconv.gox \
+		strings.gox syscall.gox
+	$(BUILDPACKAGE)
+os/user/check: $(CHECK_DEPS)
+	@$(MKDIR_P) os/user
+	@$(CHECK)
+.PHONY: os/user/check
+
 os/signal.lo: $(go_os_signal_files) runtime.gox strconv.gox
 	$(BUILDPACKAGE)
 os/signal/check: $(CHECK_DEPS)
@@ -2886,6 +3003,8 @@ go/token.gox: go/token.lo
 	$(BUILDGOX)
 go/typechecker.gox: go/typechecker.lo
 	$(BUILDGOX)
+go/types.gox: go/types.lo
+	$(BUILDGOX)
 
 hash/adler32.gox: hash/adler32.lo
 	$(BUILDGOX)
@@ -2898,15 +3017,25 @@ hash/fnv.gox: hash/fnv.lo
 
 http/cgi.gox: http/cgi.lo
 	$(BUILDGOX)
+http/fcgi.gox: http/fcgi.lo
+	$(BUILDGOX)
 http/httptest.gox: http/httptest.lo
 	$(BUILDGOX)
 http/pprof.gox: http/pprof.lo
 	$(BUILDGOX)
+http/spdy.gox: http/spdy.lo
+	$(BUILDGOX)
 
+image/gif.gox: image/gif.lo
+	$(BUILDGOX)
 image/jpeg.gox: image/jpeg.lo
 	$(BUILDGOX)
 image/png.gox: image/png.lo
 	$(BUILDGOX)
+image/tiff.gox: image/tiff.lo
+	$(BUILDGOX)
+image/ycbcr.gox: image/ycbcr.lo
+	$(BUILDGOX)
 
 index/suffixarray.gox: index/suffixarray.lo
 	$(BUILDGOX)
@@ -2924,6 +3053,8 @@ net/textproto.gox: net/textproto.lo
 
 os/inotify.gox: os/inotify.lo
 	$(BUILDGOX)
+os/user.gox: os/user.lo
+	$(BUILDGOX)
 os/signal.gox: os/signal.lo
 	$(BUILDGOX)
 
@@ -3054,22 +3185,30 @@ TEST_PACKAGES = \
 	exp/datafmt/check \
 	exp/draw/check \
 	exp/eval/check \
+	go/ast/check \
 	go/parser/check \
 	go/printer/check \
 	go/scanner/check \
 	go/token/check \
 	go/typechecker/check \
+	$(go_types_check_omitted_since_it_calls_6g) \
 	hash/adler32/check \
 	hash/crc32/check \
 	hash/crc64/check \
 	hash/fnv/check \
 	http/cgi/check \
+	http/fcgi/check \
+	http/spdy/check \
+	image/jpeg/check \
 	image/png/check \
+	image/tiff/check \
+	image/ycbcr/check \
 	index/suffixarray/check \
 	io/ioutil/check \
 	mime/multipart/check \
 	net/textproto/check \
 	$(os_inotify_check) \
+	os/user/check \
 	os/signal/check \
 	path/filepath/check \
 	rpc/jsonrpc/check \
Index: libgo/MERGE
===================================================================
--- libgo/MERGE	(revision 173685)
+++ libgo/MERGE	(working copy)
@@ -1,4 +1,4 @@
-f618e5e0991d
+aea0ba6e5935
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
Index: libgo/mksysinfo.sh
===================================================================
--- libgo/mksysinfo.sh	(revision 173685)
+++ libgo/mksysinfo.sh	(working copy)
@@ -74,6 +74,8 @@ cat > sysinfo.c <<EOF
 #include <sys/select.h>
 #endif
 #include <unistd.h>
+#include <netdb.h>
+#include <pwd.h>
 EOF
 
 ${CC} -fdump-go-spec=gen-sysinfo.go -std=gnu99 -S -o sysinfo.s sysinfo.c
@@ -403,6 +405,10 @@ else
   echo "type Rusage struct {}" >> ${OUT}
 fi
 
+# The RUSAGE constants.
+grep '^const _RUSAGE_' gen-sysinfo.go | \
+  sed -e 's/^\(const \)_\(RUSAGE_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+
 # The utsname struct.
 grep '^type _utsname ' gen-sysinfo.go | \
     sed -e 's/_utsname/Utsname/' \
@@ -456,4 +462,20 @@ if test "$fd_set" != ""; then
 fi
 echo "type fds_bits_type $fds_bits_type" >> ${OUT}
 
+# The addrinfo struct.
+grep '^type _addrinfo ' gen-sysinfo.go | \
+    sed -e 's/_addrinfo/Addrinfo/g' \
+      -e 's/ ai_/ Ai_/g' \
+    >> ${OUT}
+
+# The addrinfo flags.
+grep '^const _AI_' gen-sysinfo.go | \
+  sed -e 's/^\(const \)_\(AI_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+
+# The passwd struct.
+grep '^type _passwd ' gen-sysinfo.go | \
+    sed -e 's/_passwd/Passwd/' \
+      -e 's/ pw_/ Pw_/g' \
+    >> ${OUT}
+
 exit $?
Index: libgo/runtime/go-reflect-chan.c
===================================================================
--- libgo/runtime/go-reflect-chan.c	(revision 173685)
+++ libgo/runtime/go-reflect-chan.c	(working copy)
@@ -8,30 +8,54 @@
 #include <stdint.h>
 
 #include "config.h"
+#include "go-alloc.h"
+#include "go-assert.h"
+#include "go-panic.h"
 #include "go-type.h"
 #include "channel.h"
 
 /* This file implements support for reflection on channels.  These
    functions are called from reflect/value.go.  */
 
-extern unsigned char *makechan (const struct __go_type_descriptor *, uint32_t)
+extern uintptr_t makechan (const struct __go_type_descriptor *, uint32_t)
   asm ("libgo_reflect.reflect.makechan");
 
-unsigned char *
+uintptr_t
 makechan (const struct __go_type_descriptor *typ, uint32_t size)
 {
-  return (unsigned char *) __go_new_channel (typ->__size, size);
+  struct __go_channel *channel;
+  void *ret;
+
+  __go_assert (typ->__code == GO_CHAN);
+  typ = ((const struct __go_channel_type *) typ)->__element_type;
+
+  channel = __go_new_channel (typ, size);
+
+  ret = __go_alloc (sizeof (void *));
+  __builtin_memcpy (ret, &channel, sizeof (void *));
+  return (uintptr_t) ret;
 }
 
-extern void chansend (unsigned char *, unsigned char *, _Bool *)
+extern _Bool chansend (uintptr_t, uintptr_t, _Bool)
   asm ("libgo_reflect.reflect.chansend");
 
-void
-chansend (unsigned char *ch, unsigned char *val, _Bool *selected)
+_Bool
+chansend (uintptr_t ch, uintptr_t val_i, _Bool nb)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
+  uintptr_t element_size;
+  void *pv;
+
+  if (channel == NULL)
+    __go_panic_msg ("send to nil channel");
+
+  if (__go_is_pointer_type (channel->element_type))
+    pv = &val_i;
+  else
+    pv = (void *) val_i;
 
-  if (channel->element_size <= sizeof (uint64_t))
+  element_size = channel->element_type->__size;
+  if (element_size <= sizeof (uint64_t))
     {
       union
       {
@@ -41,35 +65,60 @@ chansend (unsigned char *ch, unsigned ch
 
       __builtin_memset (u.b, 0, sizeof (uint64_t));
 #ifndef WORDS_BIGENDIAN
-      __builtin_memcpy (u.b, val, channel->element_size);
+      __builtin_memcpy (u.b, pv, element_size);
 #else
-      __builtin_memcpy (u.b + sizeof (uint64_t) - channel->element_size, val,
-			channel->element_size);
+      __builtin_memcpy (u.b + sizeof (uint64_t) - element_size, pv,
+			element_size);
 #endif
-      if (selected == NULL)
-	__go_send_small (channel, u.v, 0);
+      if (nb)
+	return __go_send_nonblocking_small (channel, u.v);
       else
-	*selected = __go_send_nonblocking_small (channel, u.v);
+	{
+	  __go_send_small (channel, u.v, 0);
+	  return 1;
+	}
     }
   else
     {
-      if (selected == NULL)
-	__go_send_big (channel, val, 0);
+      if (nb)
+	return __go_send_nonblocking_big (channel, pv);
       else
-	*selected = __go_send_nonblocking_big (channel, val);
+	{
+	  __go_send_big (channel, pv, 0);
+	  return 1;
+	}
     }
 }
 
-extern void chanrecv (unsigned char *, unsigned char *, _Bool *, _Bool *)
+struct chanrecv_ret
+{
+  uintptr_t val;
+  _Bool selected;
+  _Bool received;
+};
+
+extern struct chanrecv_ret chanrecv (uintptr_t, _Bool)
   asm ("libgo_reflect.reflect.chanrecv");
 
-void
-chanrecv (unsigned char *ch, unsigned char *val, _Bool *selected,
-	  _Bool *received)
+struct chanrecv_ret
+chanrecv (uintptr_t ch, _Bool nb)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
+  void *pv;
+  uintptr_t element_size;
+  struct chanrecv_ret ret;
+
+  element_size = channel->element_type->__size;
 
-  if (channel->element_size <= sizeof (uint64_t))
+  if (__go_is_pointer_type (channel->element_type))
+    pv = &ret.val;
+  else
+    {
+      pv = __go_alloc (element_size);
+      ret.val = (uintptr_t) pv;
+    }
+
+  if (element_size <= sizeof (uint64_t))
     {
       union
       {
@@ -77,74 +126,73 @@ chanrecv (unsigned char *ch, unsigned ch
 	uint64_t v;
       } u;
 
-      if (selected == NULL)
-	u.v = __go_receive_small_closed (channel, 0, received);
+      if (!nb)
+	{
+	  u.v = __go_receive_small_closed (channel, 0, &ret.received);
+	  ret.selected = 1;
+	}
       else
 	{
 	  struct __go_receive_nonblocking_small s;
 
 	  s = __go_receive_nonblocking_small (channel);
-	  *selected = s.__success || s.__closed;
-	  if (received != NULL)
-	    *received = s.__success;
+	  ret.selected = s.__success || s.__closed;
+	  ret.received = s.__success;
 	  u.v = s.__val;
 	}
 
 #ifndef WORDS_BIGENDIAN
-      __builtin_memcpy (val, u.b, channel->element_size);
+      __builtin_memcpy (pv, u.b, element_size);
 #else
-      __builtin_memcpy (val, u.b + sizeof (uint64_t) - channel->element_size,
-			channel->element_size);
+      __builtin_memcpy (pv, u.b + sizeof (uint64_t) - element_size,
+			element_size);
 #endif
     }
   else
     {
-      if (selected == NULL)
+      if (!nb)
 	{
-	  _Bool success;
-
-	  success = __go_receive_big (channel, val, 0);
-	  if (received != NULL)
-	    *received = success;
+	  ret.received = __go_receive_big (channel, pv, 0);
+	  ret.selected = 1;
 	}
       else
 	{
 	  _Bool got;
 	  _Bool closed;
 
-	  got = __go_receive_nonblocking_big (channel, val, &closed);
-	  *selected = got || closed;
-	  if (received != NULL)
-	    *received = got;
+	  got = __go_receive_nonblocking_big (channel, pv, &closed);
+	  ret.selected = got || closed;
+	  ret.received = got;
 	}
     }
+
+  return ret;
 }
 
-extern void chanclose (unsigned char *)
-  asm ("libgo_reflect.reflect.chanclose");
+extern void chanclose (uintptr_t) asm ("libgo_reflect.reflect.chanclose");
 
 void
-chanclose (unsigned char *ch)
+chanclose (uintptr_t ch)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
 
   __go_builtin_close (channel);
 }
 
-extern int32_t chanlen (unsigned char *) asm ("libgo_reflect.reflect.chanlen");
+extern int32_t chanlen (uintptr_t) asm ("libgo_reflect.reflect.chanlen");
 
 int32_t
-chanlen (unsigned char *ch)
+chanlen (uintptr_t ch)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
 
   return (int32_t) __go_chan_len (channel);
 }
 
-extern int32_t chancap (unsigned char *) asm ("libgo_reflect.reflect.chancap");
+extern int32_t chancap (uintptr_t) asm ("libgo_reflect.reflect.chancap");
 
 int32_t
-chancap (unsigned char *ch)
+chancap (uintptr_t ch)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
 
Index: libgo/runtime/channel.h
===================================================================
--- libgo/runtime/channel.h	(revision 173685)
+++ libgo/runtime/channel.h	(working copy)
@@ -7,6 +7,8 @@
 #include <stdint.h>
 #include <pthread.h>
 
+#include "go-type.h"
+
 /* This structure is used when a select is waiting for a synchronous
    channel.  */
 
@@ -34,8 +36,8 @@ struct __go_channel
   /* A condition variable.  This is signalled when data is added to
      the channel and when data is removed from the channel.  */
   pthread_cond_t cond;
-  /* The size of elements on this channel.  */
-  size_t element_size;
+  /* The type of elements on this channel.  */
+  const struct __go_type_descriptor *element_type;
   /* True if a goroutine is waiting to send on a synchronous
      channel.  */
   _Bool waiting_to_send;
@@ -82,7 +84,8 @@ typedef struct __go_channel __go_channel
    acquired while this mutex is held.  */
 extern pthread_mutex_t __go_select_data_mutex;
 
-extern struct __go_channel *__go_new_channel (uintptr_t, uintptr_t);
+extern struct __go_channel *
+__go_new_channel (const struct __go_type_descriptor *, uintptr_t);
 
 extern _Bool __go_synch_with_select (struct __go_channel *, _Bool);
 
Index: libgo/runtime/go-signal.c
===================================================================
--- libgo/runtime/go-signal.c	(revision 173685)
+++ libgo/runtime/go-signal.c	(working copy)
@@ -245,3 +245,26 @@ runtime_resetcpuprofiler(int32 hz)
 
   m->profilehz = hz;
 }
+
+/* Used by the os package to raise SIGPIPE.  */
+
+void os_sigpipe (void) __asm__ ("libgo_os.os.sigpipe");
+
+void
+os_sigpipe (void)
+{
+  struct sigaction sa;
+  int i;
+
+  memset (&sa, 0, sizeof sa);
+
+  sa.sa_handler = SIG_DFL;
+
+  i = sigemptyset (&sa.sa_mask);
+  __go_assert (i == 0);
+
+  if (sigaction (SIGPIPE, &sa, NULL) != 0)
+    abort ();
+
+  raise (SIGPIPE);
+}
Index: libgo/runtime/go-send-big.c
===================================================================
--- libgo/runtime/go-send-big.c	(revision 173685)
+++ libgo/runtime/go-send-big.c	(working copy)
@@ -12,19 +12,20 @@
 void
 __go_send_big (struct __go_channel* channel, const void *val, _Bool for_select)
 {
+  uintptr_t element_size;
   size_t alloc_size;
   size_t offset;
 
   if (channel == NULL)
     __go_panic_msg ("send to nil channel");
 
-  alloc_size = ((channel->element_size + sizeof (uint64_t) - 1)
-		/ sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  alloc_size = (element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t);
 
   __go_send_acquire (channel, for_select);
 
   offset = channel->next_store * alloc_size;
-  __builtin_memcpy (&channel->data[offset], val, channel->element_size);
+  __builtin_memcpy (&channel->data[offset], val, element_size);
 
   __go_send_release (channel);
 }
Index: libgo/runtime/iface.goc
===================================================================
--- libgo/runtime/iface.goc	(revision 173685)
+++ libgo/runtime/iface.goc	(working copy)
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 package runtime
+#include "go-panic.h"
 #include "go-type.h"
 #include "interface.h"
 #define nil NULL
@@ -33,6 +34,8 @@ func ifacetype(i interface) (d *const_de
 
 // Convert an empty interface to an empty interface.
 func ifaceE2E2(e empty_interface) (ret empty_interface, ok bool) {
+	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
+		__go_panic_msg("invalid interface value");
 	ret = e;
 	ok = ret.__type_descriptor != nil;
 }
@@ -52,6 +55,8 @@ func ifaceI2E2(i interface) (ret empty_i
 
 // Convert an empty interface to a non-empty interface.
 func ifaceE2I2(inter *descriptor, e empty_interface) (ret interface, ok bool) {
+	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
+		__go_panic_msg("invalid interface value");
 	if (e.__type_descriptor == nil) {
 		ret.__methods = nil;
 		ret.__object = nil;
@@ -81,6 +86,8 @@ func ifaceI2I2(inter *descriptor, i inte
 
 // Convert an empty interface to a pointer type.
 func ifaceE2T2P(inter *descriptor, e empty_interface) (ret *void, ok bool) {
+	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
+		__go_panic_msg("invalid interface value");
 	if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
 		ret = nil;
 		ok = 0;
@@ -104,6 +111,8 @@ func ifaceI2T2P(inter *descriptor, i int
 
 // Convert an empty interface to a non-pointer type.
 func ifaceE2T2(inter *descriptor, e empty_interface, ret *void) (ok bool) {
+	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
+		__go_panic_msg("invalid interface value");
 	if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
 		__builtin_memset(ret, 0, inter->__size);
 		ok = 0;
Index: libgo/runtime/go-send-nb-small.c
===================================================================
--- libgo/runtime/go-send-nb-small.c	(revision 173685)
+++ libgo/runtime/go-send-nb-small.c	(working copy)
@@ -93,7 +93,7 @@ __go_send_nonblocking_acquire (struct __
 _Bool
 __go_send_nonblocking_small (struct __go_channel *channel, uint64_t val)
 {
-  __go_assert (channel->element_size <= sizeof (uint64_t));
+  __go_assert (channel->element_type->__size <= sizeof (uint64_t));
 
   if (!__go_send_nonblocking_acquire (channel))
     return 0;
Index: libgo/runtime/chan.goc
===================================================================
--- libgo/runtime/chan.goc	(revision 173685)
+++ libgo/runtime/chan.goc	(working copy)
@@ -13,7 +13,8 @@ typedef struct __go_channel chan;
 /* Do a channel receive with closed status.  */
 
 func chanrecv2(c *chan, val *byte) (received bool) {
-	if (c->element_size > 8) {
+	uintptr_t element_size = c->element_type->__size;
+	if (element_size > 8) {
 		return __go_receive_big(c, val, 0);
 	} else {
 		union {
@@ -23,10 +24,9 @@ func chanrecv2(c *chan, val *byte) (rece
 
 		u.v = __go_receive_small_closed(c, 0, &received);
 #ifndef WORDS_BIGENDIAN
-		__builtin_memcpy(val, u.b, c->element_size);
+		__builtin_memcpy(val, u.b, element_size);
 #else
-		__builtin_memcpy(val, u.b + 8 - c->element_size,
-				 c->element_size);
+		__builtin_memcpy(val, u.b + 8 - element_size, element_size);
 #endif
 		return received;
 	}
@@ -35,7 +35,8 @@ func chanrecv2(c *chan, val *byte) (rece
 /* Do a channel receive with closed status for a select statement.  */
 
 func chanrecv3(c *chan, val *byte) (received bool) {
-	if (c->element_size > 8) {
+	uintptr_t element_size = c->element_type->__size;
+	if (element_size > 8) {
 		return __go_receive_big(c, val, 1);
 	} else {
 		union {
@@ -45,10 +46,9 @@ func chanrecv3(c *chan, val *byte) (rece
 
 		u.v = __go_receive_small_closed(c, 1, &received);
 #ifndef WORDS_BIGENDIAN
-		__builtin_memcpy(val, u.b, c->element_size);
+		__builtin_memcpy(val, u.b, element_size);
 #else
-		__builtin_memcpy(val, u.b + 8 - c->element_size,
-				 c->element_size);
+		__builtin_memcpy(val, u.b + 8 - element_size, element_size);
 #endif
 		return received;
 	}
Index: libgo/runtime/go-reflect-call.c
===================================================================
--- libgo/runtime/go-reflect-call.c	(revision 173685)
+++ libgo/runtime/go-reflect-call.c	(working copy)
@@ -14,9 +14,32 @@
 #include "go-type.h"
 #include "runtime.h"
 
-/* Forward declaration.  */
-
-static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *);
+/* The functions in this file are only called from reflect_call.  As
+   reflect_call calls a libffi function, which will be compiled
+   without -fsplit-stack, it will always run with a large stack.  */
+
+static ffi_type *go_array_to_ffi (const struct __go_array_type *)
+  __attribute__ ((no_split_stack));
+static ffi_type *go_slice_to_ffi (const struct __go_slice_type *)
+  __attribute__ ((no_split_stack));
+static ffi_type *go_struct_to_ffi (const struct __go_struct_type *)
+  __attribute__ ((no_split_stack));
+static ffi_type *go_string_to_ffi (void) __attribute__ ((no_split_stack));
+static ffi_type *go_interface_to_ffi (void) __attribute__ ((no_split_stack));
+static ffi_type *go_complex_to_ffi (ffi_type *)
+  __attribute__ ((no_split_stack));
+static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *)
+  __attribute__ ((no_split_stack));
+static ffi_type *go_func_return_ffi (const struct __go_func_type *)
+  __attribute__ ((no_split_stack));
+static void go_func_to_cif (const struct __go_func_type *, _Bool, _Bool,
+			    ffi_cif *)
+  __attribute__ ((no_split_stack));
+static size_t go_results_size (const struct __go_func_type *)
+  __attribute__ ((no_split_stack));
+static void go_set_results (const struct __go_func_type *, unsigned char *,
+			    void **)
+  __attribute__ ((no_split_stack));
 
 /* Return an ffi_type for a Go array type.  The libffi library does
    not have any builtin support for passing arrays as values.  We work
@@ -31,7 +54,6 @@ go_array_to_ffi (const struct __go_array
   uintptr_t i;
 
   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
-  __builtin_memset (ret, 0, sizeof (ffi_type));
   ret->type = FFI_TYPE_STRUCT;
   len = descriptor->__len;
   ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *));
@@ -52,7 +74,6 @@ go_slice_to_ffi (
   ffi_type *ret;
 
   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
-  __builtin_memset (ret, 0, sizeof (ffi_type));
   ret->type = FFI_TYPE_STRUCT;
   ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
   ret->elements[0] = &ffi_type_pointer;
@@ -73,7 +94,6 @@ go_struct_to_ffi (const struct __go_stru
   int i;
 
   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
-  __builtin_memset (ret, 0, sizeof (ffi_type));
   ret->type = FFI_TYPE_STRUCT;
   field_count = descriptor->__fields.__count;
   fields = (const struct __go_struct_field *) descriptor->__fields.__values;
@@ -237,7 +257,6 @@ go_func_return_ffi (const struct __go_fu
     return go_type_to_ffi (types[0]);
 
   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
-  __builtin_memset (ret, 0, sizeof (ffi_type));
   ret->type = FFI_TYPE_STRUCT;
   ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *));
   for (i = 0; i < count; ++i)
@@ -251,7 +270,7 @@ go_func_return_ffi (const struct __go_fu
 
 static void
 go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
-		ffi_cif *cif)
+		_Bool is_method, ffi_cif *cif)
 {
   int num_params;
   const struct __go_type_descriptor **in_types;
@@ -268,10 +287,19 @@ go_func_to_cif (const struct __go_func_t
 
   num_args = num_params + (is_interface ? 1 : 0);
   args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
+  i = 0;
+  off = 0;
   if (is_interface)
-    args[0] = &ffi_type_pointer;
-  off = is_interface ? 1 : 0;
-  for (i = 0; i < num_params; ++i)
+    {
+      args[0] = &ffi_type_pointer;
+      off = 1;
+    }
+  else if (is_method)
+    {
+      args[0] = &ffi_type_pointer;
+      i = 1;
+    }
+  for (; i < num_params; ++i)
     args[i + off] = go_type_to_ffi (in_types[i]);
 
   rettype = go_func_return_ffi (func);
@@ -354,13 +382,14 @@ go_set_results (const struct __go_func_t
 
 void
 reflect_call (const struct __go_func_type *func_type, const void *func_addr,
-	      _Bool is_interface, void **params, void **results)
+	      _Bool is_interface, _Bool is_method, void **params,
+	      void **results)
 {
   ffi_cif cif;
   unsigned char *call_result;
 
   __go_assert (func_type->__common.__code == GO_FUNC);
-  go_func_to_cif (func_type, is_interface, &cif);
+  go_func_to_cif (func_type, is_interface, is_method, &cif);
 
   call_result = (unsigned char *) malloc (go_results_size (func_type));
 
Index: libgo/runtime/go-reflect-map.c
===================================================================
--- libgo/runtime/go-reflect-map.c	(revision 173685)
+++ libgo/runtime/go-reflect-map.c	(working copy)
@@ -8,69 +8,125 @@
 #include <stdint.h>
 
 #include "go-alloc.h"
+#include "go-panic.h"
 #include "go-type.h"
 #include "map.h"
 
 /* This file implements support for reflection on maps.  These
    functions are called from reflect/value.go.  */
 
-extern _Bool mapaccess (unsigned char *, unsigned char *, unsigned char *)
+struct mapaccess_ret
+{
+  uintptr_t val;
+  _Bool pres;
+};
+
+extern struct mapaccess_ret mapaccess (uintptr_t, uintptr_t)
   asm ("libgo_reflect.reflect.mapaccess");
 
-_Bool
-mapaccess (unsigned char *m, unsigned char *key, unsigned char *val)
+struct mapaccess_ret
+mapaccess (uintptr_t m, uintptr_t key_i)
 {
   struct __go_map *map = (struct __go_map *) m;
+  void *key;
+  const struct __go_type_descriptor *key_descriptor;
   void *p;
   const struct __go_type_descriptor *val_descriptor;
+  struct mapaccess_ret ret;
+  void *val;
+  void *pv;
+
+  if (map == NULL)
+    __go_panic_msg ("lookup in nil map");
+
+  key_descriptor = map->__descriptor->__map_descriptor->__key_type;
+  if (__go_is_pointer_type (key_descriptor))
+    key = &key_i;
+  else
+    key = (void *) key_i;
 
   p = __go_map_index (map, key, 0);
+
+  val_descriptor = map->__descriptor->__map_descriptor->__val_type;
+  if (__go_is_pointer_type (val_descriptor))
+    {
+      val = NULL;
+      pv = &val;
+    }
+  else
+    {
+      val = __go_alloc (val_descriptor->__size);
+      pv = val;
+    }
+
   if (p == NULL)
-    return 0;
+    ret.pres = 0;
   else
     {
-      val_descriptor = map->__descriptor->__map_descriptor->__val_type;
-      __builtin_memcpy (val, p, val_descriptor->__size);
-      return 1;
+      __builtin_memcpy (pv, p, val_descriptor->__size);
+      ret.pres = 1;
     }
+
+  ret.val = (uintptr_t) val;
+  return ret;
 }
 
-extern void mapassign (unsigned char *, unsigned char *, unsigned char *)
+extern void mapassign (uintptr_t, uintptr_t, uintptr_t, _Bool)
   asm ("libgo_reflect.reflect.mapassign");
 
 void
-mapassign (unsigned char *m, unsigned char *key, unsigned char *val)
+mapassign (uintptr_t m, uintptr_t key_i, uintptr_t val_i, _Bool pres)
 {
   struct __go_map *map = (struct __go_map *) m;
+  const struct __go_type_descriptor *key_descriptor;
+  void *key;
+
+  if (map == NULL)
+    __go_panic_msg ("lookup in nil map");
 
-  if (val == NULL)
+  key_descriptor = map->__descriptor->__map_descriptor->__key_type;
+  if (__go_is_pointer_type (key_descriptor))
+    key = &key_i;
+  else
+    key = (void *) key_i;
+
+  if (!pres)
     __go_map_delete (map, key);
   else
     {
       void *p;
       const struct __go_type_descriptor *val_descriptor;
+      void *pv;
 
       p = __go_map_index (map, key, 1);
+
       val_descriptor = map->__descriptor->__map_descriptor->__val_type;
-      __builtin_memcpy (p, val, val_descriptor->__size);
+      if (__go_is_pointer_type (val_descriptor))
+	pv = &val_i;
+      else
+	pv = (void *) val_i;
+      __builtin_memcpy (p, pv, val_descriptor->__size);
     }
 }
 
-extern int32_t maplen (unsigned char *)
+extern int32_t maplen (uintptr_t)
   asm ("libgo_reflect.reflect.maplen");
 
 int32_t
-maplen (unsigned char *m __attribute__ ((unused)))
+maplen (uintptr_t m)
 {
   struct __go_map *map = (struct __go_map *) m;
+
+  if (map == NULL)
+    return 0;
   return (int32_t) map->__element_count;
 }
 
-extern unsigned char *mapiterinit (unsigned char *)
+extern unsigned char *mapiterinit (uintptr_t)
   asm ("libgo_reflect.reflect.mapiterinit");
 
 unsigned char *
-mapiterinit (unsigned char *m)
+mapiterinit (uintptr_t m)
 {
   struct __go_hash_iter *it;
 
@@ -88,35 +144,67 @@ mapiternext (unsigned char *it)
   __go_mapiternext ((struct __go_hash_iter *) it);
 }
 
-extern _Bool mapiterkey (unsigned char *, unsigned char *)
+struct mapiterkey_ret
+{
+  uintptr_t key;
+  _Bool ok;
+};
+
+extern struct mapiterkey_ret mapiterkey (unsigned char *)
   asm ("libgo_reflect.reflect.mapiterkey");
 
-_Bool
-mapiterkey (unsigned char *ita, unsigned char *key)
+struct mapiterkey_ret
+mapiterkey (unsigned char *ita)
 {
   struct __go_hash_iter *it = (struct __go_hash_iter *) ita;
+  struct mapiterkey_ret ret;
 
   if (it->entry == NULL)
-    return 0;
+    {
+      ret.key = 0;
+      ret.ok = 0;
+    }
   else
     {
-      __go_mapiter1 (it, key);
-      return 1;
+      const struct __go_type_descriptor *key_descriptor;
+      void *key;
+      void *pk;
+
+      key_descriptor = it->map->__descriptor->__map_descriptor->__key_type;
+      if (__go_is_pointer_type (key_descriptor))
+	{
+	  key = NULL;
+	  pk = &key;
+	}
+      else
+	{
+	  key = __go_alloc (key_descriptor->__size);
+	  pk = key;
+	}
+
+      __go_mapiter1 (it, pk);
+
+      ret.key = (uintptr_t) key;
+      ret.ok = 1;
     }
+
+  return ret;
 }
 
 /* Make a new map.  We have to build our own map descriptor.  */
 
-extern unsigned char *makemap (const struct __go_map_type *)
+extern uintptr_t makemap (const struct __go_map_type *)
   asm ("libgo_reflect.reflect.makemap");
 
-unsigned char *
+uintptr_t
 makemap (const struct __go_map_type *t)
 {
   struct __go_map_descriptor *md;
   unsigned int o;
   const struct __go_type_descriptor *kt;
   const struct __go_type_descriptor *vt;
+  struct __go_map* map;
+  void *ret;
 
   /* FIXME: Reference count.  */
   md = (struct __go_map_descriptor *) __go_alloc (sizeof (*md));
@@ -135,5 +223,9 @@ makemap (const struct __go_map_type *t)
   o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
   md->__entry_size = o;
 
-  return (unsigned char *) __go_new_map (md, 0);
+  map = __go_new_map (md, 0);
+
+  ret = __go_alloc (sizeof (void *));
+  __builtin_memcpy (ret, &map, sizeof (void *));
+  return (uintptr_t) ret;
 }
Index: libgo/runtime/go-setenv.c
===================================================================
--- libgo/runtime/go-setenv.c	(revision 0)
+++ libgo/runtime/go-setenv.c	(revision 0)
@@ -0,0 +1,50 @@
+/* go-setenv.c -- set the C environment from Go.
+
+   Copyright 2011 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.  */
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "go-alloc.h"
+#include "go-string.h"
+
+/* Set the C environment from Go.  This is called by os.Setenv.  */
+
+void setenv_c (struct __go_string, struct __go_string)
+  __asm__ ("libgo_os.os.setenv_c");
+
+void
+setenv_c (struct __go_string k, struct __go_string v)
+{
+  const unsigned char *ks;
+  unsigned char *kn;
+  const unsigned char *vs;
+  unsigned char *vn;
+
+  ks = k.__data;
+  kn = NULL;
+  if (ks[k.__length] != 0)
+    {
+      kn = __go_alloc (k.__length + 1);
+      __builtin_memcpy (kn, k.__data, k.__length);
+      ks = kn;
+    }
+
+  vs = v.__data;
+  vn = NULL;
+  if (vs[v.__length] != 0)
+    {
+      vn = __go_alloc (v.__length + 1);
+      __builtin_memcpy (vn, v.__data, v.__length);
+      vs = vn;
+    }
+
+  setenv ((const char *) ks, (const char *) vs, 1);
+
+  if (kn != NULL)
+    __go_free (kn);
+  if (vn != NULL)
+    __go_free (vn);
+}
Index: libgo/runtime/go-unsafe-newarray.c
===================================================================
--- libgo/runtime/go-unsafe-newarray.c	(revision 173685)
+++ libgo/runtime/go-unsafe-newarray.c	(working copy)
@@ -5,6 +5,7 @@
    license that can be found in the LICENSE file.  */
 
 #include "go-alloc.h"
+#include "go-panic.h"
 #include "go-type.h"
 #include "interface.h"
 
@@ -21,6 +22,9 @@ NewArray (struct __go_empty_interface ty
 {
   const struct __go_type_descriptor *descriptor;
 
+  if (((uintptr_t) type.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   /* FIXME: We should check __type_descriptor to verify that this is
      really a type descriptor.  */
   descriptor = (const struct __go_type_descriptor *) type.__object;
Index: libgo/runtime/mcache.c
===================================================================
--- libgo/runtime/mcache.c	(revision 173685)
+++ libgo/runtime/mcache.c	(working copy)
@@ -22,6 +22,8 @@ runtime_MCache_Alloc(MCache *c, int32 si
 		// Replenish using central lists.
 		n = runtime_MCentral_AllocList(&runtime_mheap.central[sizeclass],
 			runtime_class_to_transfercount[sizeclass], &first);
+		if(n == 0)
+			runtime_throw("out of memory");
 		l->list = first;
 		l->nlist = n;
 		c->size += n*size;
Index: libgo/runtime/go-reflect.c
===================================================================
--- libgo/runtime/go-reflect.c	(revision 173685)
+++ libgo/runtime/go-reflect.c	(working copy)
@@ -121,6 +121,9 @@ Reflect (struct __go_empty_interface e)
 {
   struct reflect_ret ret;
 
+  if (((uintptr_t) e.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   if (e.__type_descriptor == NULL)
     {
       ret.rettype.__type_descriptor = NULL;
@@ -166,6 +169,9 @@ Typeof (const struct __go_empty_interfac
 {
   struct __go_empty_interface ret;
 
+  if (((uintptr_t) e.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   if (e.__type_descriptor == NULL)
     {
       ret.__type_descriptor = NULL;
Index: libgo/runtime/go-interface-eface-compare.c
===================================================================
--- libgo/runtime/go-interface-eface-compare.c	(revision 173685)
+++ libgo/runtime/go-interface-eface-compare.c	(working copy)
@@ -4,6 +4,7 @@
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "go-panic.h"
 #include "interface.h"
 
 /* Compare a non-empty interface value with an empty interface value.
@@ -16,6 +17,8 @@ __go_interface_empty_compare (struct __g
 {
   const struct __go_type_descriptor *left_descriptor;
 
+  if (((uintptr_t) right.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
   if (left.__methods == NULL && right.__type_descriptor == NULL)
     return 0;
   if (left.__methods == NULL || right.__type_descriptor == NULL)
Index: libgo/runtime/go-send-nb-big.c
===================================================================
--- libgo/runtime/go-send-nb-big.c	(revision 173685)
+++ libgo/runtime/go-send-nb-big.c	(working copy)
@@ -11,17 +11,18 @@
 _Bool
 __go_send_nonblocking_big (struct __go_channel* channel, const void *val)
 {
+  uintptr_t element_size;
   size_t alloc_size;
   size_t offset;
 
-  alloc_size = ((channel->element_size + sizeof (uint64_t) - 1)
-		/ sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  alloc_size = (element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t);
 
   if (!__go_send_nonblocking_acquire (channel))
     return 0;
 
   offset = channel->next_store * alloc_size;
-  __builtin_memcpy (&channel->data[offset], val, channel->element_size);
+  __builtin_memcpy (&channel->data[offset], val, element_size);
 
   __go_send_release (channel);
 
Index: libgo/runtime/go-type.h
===================================================================
--- libgo/runtime/go-type.h	(revision 173685)
+++ libgo/runtime/go-type.h	(working copy)
@@ -149,6 +149,9 @@ struct __go_array_type
   /* The element type.  */
   struct __go_type_descriptor *__element_type;
 
+  /* The type of a slice of the same element type.  */
+  struct __go_type_descriptor *__slice_type;
+
   /* The length of the array.  */
   uintptr_t __len;
 };
@@ -289,6 +292,15 @@ struct __go_struct_type
   struct __go_open_array __fields;
 };
 
+/* If an empty interface has these bits set in its type pointer, it
+   was copied from a reflect.Value and is not a valid empty
+   interface.  */
+
+enum 
+{
+  reflectFlags = 3,
+};
+
 /* Whether a type descriptor is a pointer.  */
 
 static inline _Bool
Index: libgo/runtime/malloc.goc
===================================================================
--- libgo/runtime/malloc.goc	(revision 173685)
+++ libgo/runtime/malloc.goc	(working copy)
@@ -386,7 +386,7 @@ runtime_MHeap_SysAlloc(MHeap *h, uintptr
 		return nil;
 
 	if(p < h->arena_start || (uintptr)(p+n - h->arena_start) >= MaxArena32) {
-		runtime_printf("runtime: memory allocated by OS not in usable range");
+		runtime_printf("runtime: memory allocated by OS not in usable range\n");
 		runtime_SysFree(p, n);
 		return nil;
 	}
Index: libgo/runtime/go-send-small.c
===================================================================
--- libgo/runtime/go-send-small.c	(revision 173685)
+++ libgo/runtime/go-send-small.c	(working copy)
@@ -147,7 +147,7 @@ __go_send_small (struct __go_channel *ch
   if (channel == NULL)
     __go_panic_msg ("send to nil channel");
 
-  __go_assert (channel->element_size <= sizeof (uint64_t));
+  __go_assert (channel->element_type->__size <= sizeof (uint64_t));
 
   __go_send_acquire (channel, for_select);
 
Index: libgo/runtime/go-new-channel.c
===================================================================
--- libgo/runtime/go-new-channel.c	(revision 173685)
+++ libgo/runtime/go-new-channel.c	(working copy)
@@ -13,12 +13,16 @@
 #include "channel.h"
 
 struct __go_channel*
-__go_new_channel (uintptr_t element_size, uintptr_t entries)
+__go_new_channel (const struct __go_type_descriptor *element_type,
+		  uintptr_t entries)
 {
+  uintptr_t element_size;
   struct __go_channel* ret;
   size_t alloc_size;
   int i;
 
+  element_size = element_type->__size;
+
   if ((uintptr_t) (int) entries != entries
       || entries > (uintptr_t) -1 / element_size)
     __go_panic_msg ("chan size out of range");
@@ -40,7 +44,7 @@ __go_new_channel (uintptr_t element_size
   __go_assert (i == 0);
   i = pthread_cond_init (&ret->cond, NULL);
   __go_assert (i == 0);
-  ret->element_size = element_size;
+  ret->element_type = element_type;
   ret->waiting_to_send = 0;
   ret->waiting_to_receive = 0;
   ret->selected_for_send = 0;
Index: libgo/runtime/go-rec-big.c
===================================================================
--- libgo/runtime/go-rec-big.c	(revision 173685)
+++ libgo/runtime/go-rec-big.c	(working copy)
@@ -15,23 +15,24 @@
 _Bool
 __go_receive_big (struct __go_channel *channel, void *val, _Bool for_select)
 {
+  uintptr_t element_size;
   size_t alloc_size;
   size_t offset;
 
   if (channel == NULL)
     __go_panic_msg ("receive from nil channel");
 
-  alloc_size = ((channel->element_size + sizeof (uint64_t) - 1)
-		/ sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  alloc_size = (element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t);
 
   if (!__go_receive_acquire (channel, for_select))
     {
-      __builtin_memset (val, 0, channel->element_size);
+      __builtin_memset (val, 0, element_size);
       return 0;
     }
 
   offset = channel->next_fetch * alloc_size;
-  __builtin_memcpy (val, &channel->data[offset], channel->element_size);
+  __builtin_memcpy (val, &channel->data[offset], element_size);
 
   __go_receive_release (channel);
 
Index: libgo/runtime/go-rec-nb-small.c
===================================================================
--- libgo/runtime/go-rec-nb-small.c	(revision 173685)
+++ libgo/runtime/go-rec-nb-small.c	(working copy)
@@ -94,9 +94,11 @@ __go_receive_nonblocking_acquire (struct
 struct __go_receive_nonblocking_small
 __go_receive_nonblocking_small (struct __go_channel *channel)
 {
+  uintptr_t element_size;
   struct __go_receive_nonblocking_small ret;
 
-  __go_assert (channel->element_size <= sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  __go_assert (element_size <= sizeof (uint64_t));
 
   int data = __go_receive_nonblocking_acquire (channel);
   if (data != RECEIVE_NONBLOCKING_ACQUIRE_DATA)
Index: libgo/runtime/go-type-eface.c
===================================================================
--- libgo/runtime/go-type-eface.c	(revision 173685)
+++ libgo/runtime/go-type-eface.c	(working copy)
@@ -5,6 +5,7 @@
    license that can be found in the LICENSE file.  */
 
 #include "interface.h"
+#include "go-panic.h"
 #include "go-type.h"
 
 /* A hash function for an empty interface.  */
@@ -43,6 +44,9 @@ __go_type_equal_empty_interface (const v
   v2 = (const struct __go_empty_interface *) vv2;
   v1_descriptor = v1->__type_descriptor;
   v2_descriptor = v2->__type_descriptor;
+  if (((uintptr_t) v1_descriptor & reflectFlags) != 0
+      || ((uintptr_t) v2_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
   if (v1_descriptor == NULL || v2_descriptor == NULL)
     return v1_descriptor == v2_descriptor;
   if (!__go_type_descriptors_equal (v1_descriptor, v2_descriptor))
Index: libgo/runtime/runtime.h
===================================================================
--- libgo/runtime/runtime.h	(revision 173685)
+++ libgo/runtime/runtime.h	(working copy)
@@ -194,8 +194,8 @@ void	runtime_resetcpuprofiler(int32);
 void	runtime_setcpuprofilerate(void(*)(uintptr*, int32), int32);
 
 struct __go_func_type;
-void reflect_call(const struct __go_func_type *, const void *, _Bool, void **,
-		  void **)
+void reflect_call(const struct __go_func_type *, const void *, _Bool, _Bool,
+		  void **, void **)
   asm ("libgo_reflect.reflect.call");
 
 #ifdef __rtems__
Index: libgo/runtime/go-unreflect.c
===================================================================
--- libgo/runtime/go-unreflect.c	(revision 173685)
+++ libgo/runtime/go-unreflect.c	(working copy)
@@ -5,6 +5,7 @@
    license that can be found in the LICENSE file.  */
 
 #include "go-alloc.h"
+#include "go-panic.h"
 #include "go-type.h"
 #include "interface.h"
 
@@ -19,6 +20,9 @@ Unreflect (struct __go_empty_interface t
 {
   struct __go_empty_interface ret;
 
+  if (((uintptr_t) type.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   /* FIXME: We should check __type_descriptor to verify that this is
      really a type descriptor.  */
   ret.__type_descriptor = type.__object;
Index: libgo/runtime/go-rec-nb-big.c
===================================================================
--- libgo/runtime/go-rec-nb-big.c	(revision 173685)
+++ libgo/runtime/go-rec-nb-big.c	(working copy)
@@ -14,23 +14,24 @@ _Bool
 __go_receive_nonblocking_big (struct __go_channel* channel, void *val,
 			      _Bool *closed)
 {
+  uintptr_t element_size;
   size_t alloc_size;
   size_t offset;
 
-  alloc_size = ((channel->element_size + sizeof (uint64_t) - 1)
-		/ sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  alloc_size = (element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t);
 
   int data = __go_receive_nonblocking_acquire (channel);
   if (data != RECEIVE_NONBLOCKING_ACQUIRE_DATA)
     {
-      __builtin_memset (val, 0, channel->element_size);
+      __builtin_memset (val, 0, element_size);
       if (closed != NULL)
 	*closed = data == RECEIVE_NONBLOCKING_ACQUIRE_CLOSED;
       return 0;
     }
 
   offset = channel->next_fetch * alloc_size;
-  __builtin_memcpy (val, &channel->data[offset], channel->element_size);
+  __builtin_memcpy (val, &channel->data[offset], element_size);
 
   __go_receive_release (channel);
 
Index: libgo/runtime/go-eface-val-compare.c
===================================================================
--- libgo/runtime/go-eface-val-compare.c	(revision 173685)
+++ libgo/runtime/go-eface-val-compare.c	(working copy)
@@ -4,6 +4,7 @@
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "go-panic.h"
 #include "go-type.h"
 #include "interface.h"
 
@@ -19,6 +20,8 @@ __go_empty_interface_value_compare (
   const struct __go_type_descriptor *left_descriptor;
 
   left_descriptor = left.__type_descriptor;
+  if (((uintptr_t) left_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
   if (left_descriptor == NULL)
     return 1;
   if (!__go_type_descriptors_equal (left_descriptor, right_descriptor))
Index: libgo/runtime/reflect.goc
===================================================================
--- libgo/runtime/reflect.goc	(revision 173685)
+++ libgo/runtime/reflect.goc	(working copy)
@@ -5,31 +5,27 @@
 package reflect
 #include "go-type.h"
 #include "interface.h"
-#define nil NULL
-typedef unsigned char byte;
+#include "runtime.h"
+#include "go-panic.h"
 
+typedef struct __go_type_descriptor Type;
 typedef struct __go_interface Iface;
 typedef struct __go_empty_interface Eface;
 
-func setiface(typ *byte, x *byte, ret *byte) {
-	struct __go_interface_type *t;
-	const struct __go_type_descriptor* xt;
+func ifaceE2I(inter *Type, e Eface, ret *Iface) {
+	const Type *t;
+	Eface err;
 
-	/* FIXME: We should check __type_descriptor to verify that
-	   this is really a type descriptor.  */
-	t = (struct __go_interface_type *)typ;
-	if(t->__methods.__count == 0) {
-		// already an empty interface
-		*(Eface*)ret = *(Eface*)x;
-		return;
+	if(((uintptr)e.__type_descriptor&reflectFlags) != 0)
+		runtime_throw("invalid interface value");
+	t = e.__type_descriptor;
+	if(t == nil) {
+		// explicit conversions require non-nil interface value.
+		newTypeAssertionError(nil, nil, inter,
+			nil, nil, inter->__reflection,
+			nil, &err);
+		__go_panic(err);
 	}
-	xt = ((Eface*)x)->__type_descriptor;
-	if(xt == nil) {
-		// can assign nil to any interface
-		((Iface*)ret)->__methods = nil;
-		((Iface*)ret)->__object = nil;
-		return;
-	}
-	((Iface*)ret)->__methods = __go_convert_interface(&t->__common, xt);
-	((Iface*)ret)->__object = ((Eface*)x)->__object;
+	ret->__object = e.__object;
+	ret->__methods = __go_convert_interface(inter, t);
 }
Index: libgo/runtime/go-unsafe-new.c
===================================================================
--- libgo/runtime/go-unsafe-new.c	(revision 173685)
+++ libgo/runtime/go-unsafe-new.c	(working copy)
@@ -5,6 +5,7 @@
    license that can be found in the LICENSE file.  */
 
 #include "go-alloc.h"
+#include "go-panic.h"
 #include "go-type.h"
 #include "interface.h"
 
@@ -20,6 +21,9 @@ New (struct __go_empty_interface type)
 {
   const struct __go_type_descriptor *descriptor;
 
+  if (((uintptr_t) type.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   /* FIXME: We should check __type_descriptor to verify that this is
      really a type descriptor.  */
   descriptor = (const struct __go_type_descriptor *) type.__object;
Index: libgo/runtime/go-rec-small.c
===================================================================
--- libgo/runtime/go-rec-small.c	(revision 173685)
+++ libgo/runtime/go-rec-small.c	(working copy)
@@ -266,12 +266,14 @@ uint64_t
 __go_receive_small_closed (struct __go_channel *channel, _Bool for_select,
 			   _Bool *received)
 {
+  uintptr_t element_size;
   uint64_t ret;
 
   if (channel == NULL)
     __go_panic_msg ("receive from nil channel");
 
-  __go_assert (channel->element_size <= sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  __go_assert (element_size <= sizeof (uint64_t));
 
   if (!__go_receive_acquire (channel, for_select))
     {
Index: libgo/runtime/mgc0.c
===================================================================
--- libgo/runtime/mgc0.c	(revision 173685)
+++ libgo/runtime/mgc0.c	(working copy)
@@ -90,6 +90,11 @@ scanblock(byte *b, int64 n)
 	void **bw, **w, **ew;
 	Workbuf *wbuf;
 
+	if((int64)(uintptr)n != n || n < 0) {
+		// runtime_printf("scanblock %p %lld\n", b, (long long)n);
+		runtime_throw("scanblock");
+	}
+
 	// Memory arena parameters.
 	arena_start = runtime_mheap.arena_start;
 	
@@ -602,7 +607,7 @@ runfinq(void* dummy)
 
 			next = f->next;
 			params[0] = &f->arg;
-			reflect_call(f->ft, (void*)f->fn, 0, params, nil);
+			reflect_call(f->ft, (void*)f->fn, 0, 0, params, nil);
 			f->fn = nil;
 			f->arg = nil;
 			f->next = nil;
Index: libgo/runtime/go-eface-compare.c
===================================================================
--- libgo/runtime/go-eface-compare.c	(revision 173685)
+++ libgo/runtime/go-eface-compare.c	(working copy)
@@ -4,6 +4,7 @@
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "go-panic.h"
 #include "interface.h"
 
 /* Compare two interface values.  Return 0 for equal, not zero for not
@@ -16,6 +17,11 @@ __go_empty_interface_compare (struct __g
   const struct __go_type_descriptor *left_descriptor;
 
   left_descriptor = left.__type_descriptor;
+
+  if (((uintptr_t) left_descriptor & reflectFlags) != 0
+      || ((uintptr_t) right.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   if (left_descriptor == NULL && right.__type_descriptor == NULL)
     return 0;
   if (left_descriptor == NULL || right.__type_descriptor == NULL)
Index: libgo/runtime/mheap.c
===================================================================
--- libgo/runtime/mheap.c	(revision 173685)
+++ libgo/runtime/mheap.c	(working copy)
@@ -181,9 +181,7 @@ MHeap_Grow(MHeap *h, uintptr npage)
 	// Allocate a multiple of 64kB (16 pages).
 	npage = (npage+15)&~15;
 	ask = npage<<PageShift;
-	if(ask > (uintptr)(h->arena_end - h->arena_used))
-		return false;
-	if(ask < HeapAllocChunk && HeapAllocChunk <= h->arena_end - h->arena_used)
+	if(ask < HeapAllocChunk)
 		ask = HeapAllocChunk;
 
 	v = runtime_MHeap_SysAlloc(h, ask);
@@ -192,8 +190,10 @@ MHeap_Grow(MHeap *h, uintptr npage)
 			ask = npage<<PageShift;
 			v = runtime_MHeap_SysAlloc(h, ask);
 		}
-		if(v == nil)
+		if(v == nil) {
+			runtime_printf("runtime: out of memory: cannot allocate %llu-byte block (%llu in use)\n", (unsigned long long)ask, (unsigned long long)mstats.heap_sys);
 			return false;
+		}
 	}
 	mstats.heap_sys += ask;
 
Index: libgo/syscalls/syscall_unix.go
===================================================================
--- libgo/syscalls/syscall_unix.go	(revision 173685)
+++ libgo/syscalls/syscall_unix.go	(working copy)
@@ -56,3 +56,12 @@ func munmap(addr uintptr, length uintptr
 	}
 	return
 }
+
+func libc_getrusage(who int, rusage *Rusage) int __asm__ ("getrusage")
+
+func Getrusage(who int, rusage *Rusage) (errno int) {
+	if libc_getrusage(who, rusage) < 0 {
+		errno = GetErrno()
+	}
+	return
+}
Index: libgo/syscalls/stringbyte.go
===================================================================
--- libgo/syscalls/stringbyte.go	(revision 173685)
+++ libgo/syscalls/stringbyte.go	(working copy)
@@ -6,6 +6,8 @@
 
 package syscall
 
+import "unsafe"
+
 // StringByteSlice returns a NUL-terminated slice of bytes
 // containing the text of s.
 func StringByteSlice(s string) []byte {
@@ -22,3 +24,14 @@ func StringBytePtr(s string) *byte {
 	p := StringByteSlice(s);
 	return &p[0];
 }
+
+// BytePtrToString takes a NUL-terminated array of bytes and convert
+// it to a Go string.
+func BytePtrToString(p *byte) string {
+	a := (*[10000]byte)(unsafe.Pointer(p))
+	i := 0
+	for a[i] != 0 {
+		i++
+	}
+	return string(a[:i])
+}

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-20  9:44 Go patch committed: Update to current Go library Ian Lance Taylor
@ 2011-05-20 14:18 ` Rainer Orth
  2011-05-20 14:37   ` Jakub Jelinek
                     ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Rainer Orth @ 2011-05-20 14:18 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, gofrontend-dev

Ian Lance Taylor <iant@google.com> writes:

> I have committed a patch to update libgo to the current version of the
> Go library.  This patch includes some minor changes to the Go frontend
> and to the testsuite.  The patch is too large to include here, but most
> of it is simply a copy of the changes to the master Go library.  I have
> appended the changes to the files which are not in the master library.
> Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
> Committed to mainline.

This broke Solaris bootstrap:

> Index: libgo/mksysinfo.sh
> ===================================================================
> --- libgo/mksysinfo.sh	(revision 173685)
> +++ libgo/mksysinfo.sh	(working copy)
> @@ -74,6 +74,8 @@ cat > sysinfo.c <<EOF
>  #include <sys/select.h>
>  #endif
>  #include <unistd.h>
> +#include <netdb.h>
> +#include <pwd.h>
>  EOF

<pwd.h> includes <stdio.h>, which leads to

// type ___FILE struct { _cnt int32; _ptr *uint8; _base *uint8; _flag uint8; _magic uint8; __orientation INVALID-bit-field; __ionolock INVALID-bit-field; __seekable INVALID-bit-field; __extendedfd INVALID-bit-field; __xf_nocheck INVALID-bit-field; __filler INVALID-bit-field; }
// type _FILE struct { _cnt int32; _ptr *uint8; _base *uint8; _flag uint8; _magi
c uint8; __orientation INVALID-bit-field; __ionolock INVALID-bit-field; __seekab
le INVALID-bit-field; __extendedfd INVALID-bit-field; __xf_nocheck INVALID-bit-f
ield; __filler INVALID-bit-field; }
var ___iob [59+1]___FILE
var __lastbuf *_FILE

in gen-sysinfo.go.

On recent Solaris 11, I also have:

const __PATH_SYSVOL = "/system/volatile"
const __PATH_UTMPX = __PATH_SYSVOL "/utmpx"
const __PATH_VARRUN = __PATH_SYSVOL "/"

For the moment, I'm just omitting the offending declarations in
mksysinfo.sh.

IRIX might have similar issues, I'm currently checking.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-20 14:18 ` Rainer Orth
@ 2011-05-20 14:37   ` Jakub Jelinek
  2011-05-20 19:31     ` Ian Lance Taylor
  2011-05-20 18:09   ` Rainer Orth
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Jakub Jelinek @ 2011-05-20 14:37 UTC (permalink / raw)
  To: Rainer Orth; +Cc: Ian Lance Taylor, gcc-patches, gofrontend-dev

On Fri, May 20, 2011 at 03:44:07PM +0200, Rainer Orth wrote:
> Ian Lance Taylor <iant@google.com> writes:
> 
> > I have committed a patch to update libgo to the current version of the
> > Go library.  This patch includes some minor changes to the Go frontend
> > and to the testsuite.  The patch is too large to include here, but most
> > of it is simply a copy of the changes to the master Go library.  I have
> > appended the changes to the files which are not in the master library.
> > Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
> > Committed to mainline.
> 
> This broke Solaris bootstrap:

It broke Linux bootstrap too.
<netdb.h> includes <netinet/in.h> which has:
enum
  {
    IPPORT_ECHO = 7,            /* Echo service.  */
...
    IPPORT_RESERVED = 1024,
...
  };
and later on has:
#ifdef __USE_XOPEN2K
/* Highest reserved Internet port number.  */
# define IPPORT_RESERVED        1024
#endif

mksysinfo.sh then manages to put const _IPPORT_RESERVED into sysinfo.go
twice.

	Jakub

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-20 14:18 ` Rainer Orth
  2011-05-20 14:37   ` Jakub Jelinek
@ 2011-05-20 18:09   ` Rainer Orth
  2011-05-24 22:41     ` Ian Lance Taylor
  2011-05-20 18:26   ` Rainer Orth
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Rainer Orth @ 2011-05-20 18:09 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, gofrontend-dev

There are more issues on Solaris, though:

/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_bsd.go:13:25: error: expected package
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_bsd.go:13:30: error: expected ';' or newline after top level declaration
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_bsd.go:15:1: error: expected declaration

There's no C package in gcc libgo, so I'm removing that.  But even with that
fix, cgo_bsd.go doesn't compile on Solaris:

/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_bsd.go:14:17: error: reference to undefined identifier 'syscall.AI_MASK'

It seems that cgo_linux.go should be the default, which is what the
patch below does.  Btw., dealing with deeply nested automake
conditionals is a total mess.  What about a patch to move the logic to
select the various variants to configure.ac and substitute the result
into Makefile?

/vol/gcc/src/hg/trunk/local/libgo/go/net/sock_bsd.go:21:55: error: reference to undefined identifier 'syscall.SO_REUSEPORT'

SO_REUSEPORT doesn't exist on Solaris.  Again, sock_linux.go seems to be
generic and should become the default (losing the name, perhaps use
cgo_posix instead?).

IRIX has the same issue (and more, to be reported separately).

This patch (and the mksysinfo.go hack for _FILE/___FILE) allowed me to
build libgo.so on Solaris 10/x86.

	Rainer


2011-05-20  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	libgo:
	* Makefile.am (go_net_sock_file): Use go/net/cgo_linux.go if
	LIBGO_IS_IRIX or LIBGO_IS_SOLARIS.
	(go_net_sock_file): Use go/net/sock_linux.go if
	LIBGO_IS_IRIX or LIBGO_IS_SOLARIS.
	* Makefile.in: Regenerate.
	* go/net/cgo_bsd.go: Don't refer to C.int.

diff --git a/libgo/Makefile.am b/libgo/Makefile.am
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -669,9 +669,19 @@ if LIBGO_IS_LINUX
 go_net_cgo_file = go/net/cgo_linux.go
 go_net_sock_file = go/net/sock_linux.go
 else
+if LIBGO_IS_IRIX
+go_net_cgo_file = go/net/cgo_linux.go
+go_net_sock_file = go/net/sock_linux.go
+else
+if LIBGO_IS_SOLARIS
+go_net_cgo_file = go/net/cgo_linux.go
+go_net_sock_file = go/net/sock_linux.go
+else
 go_net_cgo_file = go/net/cgo_bsd.go
 go_net_sock_file = go/net/sock_bsd.go
 endif
+endif
+endif
 
 go_net_files = \
 	go/net/cgo_unix.go \
diff --git a/libgo/go/net/cgo_bsd.go b/libgo/go/net/cgo_bsd.go
--- a/libgo/go/net/cgo_bsd.go
+++ b/libgo/go/net/cgo_bsd.go
@@ -10,6 +10,6 @@ package net
 
 import "syscall"
 
-func cgoAddrInfoMask() C.int {
+func cgoAddrInfoMask() int {
 	return syscall.AI_MASK
 }

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-20 14:18 ` Rainer Orth
  2011-05-20 14:37   ` Jakub Jelinek
  2011-05-20 18:09   ` Rainer Orth
@ 2011-05-20 18:26   ` Rainer Orth
  2011-05-24 23:33     ` Ian Lance Taylor
  2011-05-25  0:24     ` Ian Lance Taylor
  2011-05-24 21:33   ` Ian Lance Taylor
  2011-05-24 22:01   ` Ian Lance Taylor
  4 siblings, 2 replies; 15+ messages in thread
From: Rainer Orth @ 2011-05-20 18:26 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, gofrontend-dev

Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> IRIX might have similar issues, I'm currently checking.

It didn't, but there are two others:

/vol/gcc/src/hg/trunk/local/libgo/runtime/go-setenv.c: In function 'setenv_c':
/vol/gcc/src/hg/trunk/local/libgo/runtime/go-setenv.c:44:3: error: implicit declaration of function 'setenv' [-Werror=implicit-function-declaration]

One needs to check for putenv vs. setenv and handle that in
go-setenv.c.  I've hacked around the issue for the moment to at least
let bootstrap succeed.

Besides, there are many errors compiling cgo_unix.go and cgo_linux.go:

/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:23:57: error: expected type
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:23:81: error: expected type
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:24:29: error: expected type
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:36:11: error: expected type
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:37:12: error: expected type
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:82:11: error: expected type
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:83:12: error: expected type

sysinfo.go lacks Addrinfo here.

/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:91:34: error: reference to undefined identifier 'syscall.AI_ALL'
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:91:51: error: reference to undefined identifier 'syscall.AI_V4MAPPED'
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:91:73: error: reference to undefined identifier 'syscall.AI_CANONNAME'
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:97:24: error: reference to undefined identifier 'syscall.EAI_NONAME'
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_unix.go:99:31: error: reference to undefined identifier 'syscall.EAI_SYSTEM'
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_linux.go:14:17: error: reference to undefined identifier 'syscall.AI_CANONNAME'
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_linux.go:14:40: error: reference to undefined identifier 'syscall.AI_V4MAPPED'
/vol/gcc/src/hg/trunk/local/libgo/go/net/cgo_linux.go:14:62: error: reference to undefined identifier 'syscall.AI_ALL'

All those errors are caused by the fact that <netdb.h> only exposes
struct addrinfo and the AI_* and EAI_* defines if _NO_XOPEN4 &&
_NO_XOPEN5, but we need _XOPEN_SOURCE=500 for other reasons.  So I've
again chosen to hardcode them in socket_irix.go.

With this patch (and the setenv/putenv hack), I've been able to
successfully build libgo.so on IRIX 6.5.

	Rainer


2011-05-20  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	libgo:
	* syscalls/socket_irix.go (Addrinfo): Define.
        Declare AI_*, EAI_* constants.

diff --git a/libgo/syscalls/socket_irix.go b/libgo/syscalls/socket_irix.go
--- a/libgo/syscalls/socket_irix.go
+++ b/libgo/syscalls/socket_irix.go
@@ -82,3 +82,44 @@ type IpMreq struct {
 	Multiaddr [4]byte
 	Interface [4]byte
 }
+
+// Similarly, <netdb.h> only provides struct addrinfo, AI_* and EAI_* if
+// _NO_XOPEN4 && _NO_XOPEN5.
+type Addrinfo struct {
+	Ai_flags int32
+	Ai_family int32
+	Ai_socktype int32
+	Ai_protocol int32
+	Ai_addrlen int32
+	Ai_canonname *uint8
+	Ai_addr *_sockaddr
+	Ai_next *Addrinfo
+}
+
+const (
+	AI_PASSIVE	= 0x00000001
+	AI_CANONNAME	= 0x00000002
+	AI_NUMERICHOST	= 0x00000004
+	AI_NUMERICSERV	= 0x00000008
+	AI_ALL		= 0x00000100
+	AI_ADDRCONFIG	= 0x00000400
+	AI_V4MAPPED	= 0x00000800
+	AI_DEFAULT	= (AI_V4MAPPED | AI_ADDRCONFIG)
+)
+
+const (
+	EAI_ADDRFAMILY	=  1
+	EAI_AGAIN	=  2
+	EAI_BADFLAGS	=  3
+	EAI_FAIL	=  4
+	EAI_FAMILY	=  5
+	EAI_MEMORY	=  6
+	EAI_NODATA	=  7
+	EAI_NONAME	=  8
+	EAI_SERVICE	=  9
+	EAI_SOCKTYPE	= 10
+	EAI_SYSTEM	= 11
+	EAI_BADHINTS	= 12
+	EAI_OVERFLOW	= 13
+	EAI_MAX		= 14
+)

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-20 14:37   ` Jakub Jelinek
@ 2011-05-20 19:31     ` Ian Lance Taylor
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Lance Taylor @ 2011-05-20 19:31 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Rainer Orth, gcc-patches, gofrontend-dev

Jakub Jelinek <jakub@redhat.com> writes:

> It broke Linux bootstrap too.
> <netdb.h> includes <netinet/in.h> which has:
> enum
>   {
>     IPPORT_ECHO = 7,            /* Echo service.  */
> ...
>     IPPORT_RESERVED = 1024,
> ...
>   };
> and later on has:
> #ifdef __USE_XOPEN2K
> /* Highest reserved Internet port number.  */
> # define IPPORT_RESERVED        1024
> #endif
>
> mksysinfo.sh then manages to put const _IPPORT_RESERVED into sysinfo.go
> twice.

This one should now be fixed.  I forgot to commit a patch to godump.c.
Sorry about that.

Ian

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-20 14:18 ` Rainer Orth
                     ` (2 preceding siblings ...)
  2011-05-20 18:26   ` Rainer Orth
@ 2011-05-24 21:33   ` Ian Lance Taylor
  2011-05-25 19:11     ` Rainer Orth
  2011-05-24 22:01   ` Ian Lance Taylor
  4 siblings, 1 reply; 15+ messages in thread
From: Ian Lance Taylor @ 2011-05-24 21:33 UTC (permalink / raw)
  To: Rainer Orth; +Cc: gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 1217 bytes --]

Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> <pwd.h> includes <stdio.h>, which leads to
>
> // type ___FILE struct { _cnt int32; _ptr *uint8; _base *uint8; _flag uint8; _magic uint8; __orientation INVALID-bit-field; __ionolock INVALID-bit-field; __seekable INVALID-bit-field; __extendedfd INVALID-bit-field; __xf_nocheck INVALID-bit-field; __filler INVALID-bit-field; }
> // type _FILE struct { _cnt int32; _ptr *uint8; _base *uint8; _flag uint8; _magi
> c uint8; __orientation INVALID-bit-field; __ionolock INVALID-bit-field; __seekab
> le INVALID-bit-field; __extendedfd INVALID-bit-field; __xf_nocheck INVALID-bit-f
> ield; __filler INVALID-bit-field; }
> var ___iob [59+1]___FILE
> var __lastbuf *_FILE
>
> in gen-sysinfo.go.

I just committed a patch to godump.c which I think should fix this
issue.  Let me know if it doesn't.

Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian


2011-05-24  Ian Lance Taylor  <iant@google.com>

	* godump.c (struct godump_container): Add invalid_hash field.
	(go_format_type): Return false if type is found in invalid_hash.
	(go_output_typedef): Add invalid type to invalid_hash.
	(go_finish): Create and delete invalid_hash.



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 3090 bytes --]

Index: godump.c
===================================================================
--- godump.c	(revision 174138)
+++ godump.c	(working copy)
@@ -464,6 +464,9 @@ struct godump_container
   /* Global type definitions.  */
   htab_t type_hash;
 
+  /* Invalid types.  */
+  htab_t invalid_hash;
+
   /* Obstack used to write out a type definition.  */
   struct obstack type_obstack;
 };
@@ -500,20 +503,20 @@ go_format_type (struct godump_container 
 	  || TREE_CODE (type) == FUNCTION_TYPE))
     {
       tree name;
+      void **slot;
 
       name = TYPE_NAME (type);
-      if (TREE_CODE (name) == IDENTIFIER_NODE)
-	{
-	  obstack_1grow (ob, '_');
-	  go_append_string (ob, name);
-	  return ret;
-	}
-      else if (TREE_CODE (name) == TYPE_DECL)
-	{
-	  obstack_1grow (ob, '_');
-	  go_append_string (ob, DECL_NAME (name));
-	  return ret;
-	}
+      if (TREE_CODE (name) == TYPE_DECL)
+	name = DECL_NAME (name);
+
+      slot = htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER (name),
+			     NO_INSERT);
+      if (slot != NULL)
+	ret = false;
+
+      obstack_1grow (ob, '_');
+      go_append_string (ob, name);
+      return ret;
     }
 
   pointer_set_insert (container->decls_seen, type);
@@ -879,7 +882,11 @@ go_output_typedef (struct godump_contain
       *slot = CONST_CAST (void *, (const void *) type);
 
       if (!go_format_type (container, TREE_TYPE (decl), false, false))
-	fprintf (go_dump_file, "// ");
+	{
+	  fprintf (go_dump_file, "// ");
+	  slot = htab_find_slot (container->invalid_hash, type, INSERT);
+	  *slot = CONST_CAST (void *, (const void *) type);
+	}
       fprintf (go_dump_file, "type _%s ",
 	       IDENTIFIER_POINTER (DECL_NAME (decl)));
       go_output_type (container);
@@ -898,7 +905,11 @@ go_output_typedef (struct godump_contain
        *slot = CONST_CAST (void *, (const void *) type);
 
        if (!go_format_type (container, TREE_TYPE (decl), false, false))
-	 fprintf (go_dump_file, "// ");
+	 {
+	   fprintf (go_dump_file, "// ");
+	   slot = htab_find_slot (container->invalid_hash, type, INSERT);
+	   *slot = CONST_CAST (void *, (const void *) type);
+	 }
        fprintf (go_dump_file, "type _%s ",
 	       IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))));
        go_output_type (container);
@@ -1010,6 +1021,8 @@ go_finish (const char *filename)
   container.pot_dummy_types = pointer_set_create ();
   container.type_hash = htab_create (100, htab_hash_string,
                                      string_hash_eq, NULL);
+  container.invalid_hash = htab_create (10, htab_hash_string,
+					string_hash_eq, NULL);
   container.keyword_hash = htab_create (50, htab_hash_string,
                                         string_hash_eq, NULL);
   obstack_init (&container.type_obstack);
@@ -1044,6 +1057,7 @@ go_finish (const char *filename)
   pointer_set_destroy (container.decls_seen);
   pointer_set_destroy (container.pot_dummy_types);
   htab_delete (container.type_hash);
+  htab_delete (container.invalid_hash);
   htab_delete (container.keyword_hash);
   obstack_free (&container.type_obstack, NULL);
 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-20 14:18 ` Rainer Orth
                     ` (3 preceding siblings ...)
  2011-05-24 21:33   ` Ian Lance Taylor
@ 2011-05-24 22:01   ` Ian Lance Taylor
  4 siblings, 0 replies; 15+ messages in thread
From: Ian Lance Taylor @ 2011-05-24 22:01 UTC (permalink / raw)
  To: Rainer Orth; +Cc: gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 571 bytes --]

Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> On recent Solaris 11, I also have:
>
> const __PATH_SYSVOL = "/system/volatile"
> const __PATH_UTMPX = __PATH_SYSVOL "/utmpx"
> const __PATH_VARRUN = __PATH_SYSVOL "/"
>
> For the moment, I'm just omitting the offending declarations in
> mksysinfo.sh.

This patch should fix this problem.  Bootstrapped and ran Go testsuite
on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2011-05-24  Ian Lance Taylor  <iant@google.com>

	* godump.c (go_define): Don't accept a string immediately after
	another operand.



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 397 bytes --]

Index: godump.c
===================================================================
--- godump.c	(revision 174140)
+++ godump.c	(working copy)
@@ -300,7 +300,11 @@ go_define (unsigned int lineno, const ch
 	case '"':
 	case '\'':
 	  {
-	    char quote = *p;
+	    char quote;
+
+	    if (saw_operand)
+	      goto unknown;
+	    quote = *p;
 	    *q++ = *p++;
 	    while (*p != quote)
 	      {

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-20 18:09   ` Rainer Orth
@ 2011-05-24 22:41     ` Ian Lance Taylor
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Lance Taylor @ 2011-05-24 22:41 UTC (permalink / raw)
  To: Rainer Orth; +Cc: gcc-patches, gofrontend-dev

Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> 2011-05-20  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
>
> 	libgo:
> 	* Makefile.am (go_net_sock_file): Use go/net/cgo_linux.go if
> 	LIBGO_IS_IRIX or LIBGO_IS_SOLARIS.
> 	(go_net_sock_file): Use go/net/sock_linux.go if
> 	LIBGO_IS_IRIX or LIBGO_IS_SOLARIS.
> 	* Makefile.in: Regenerate.
> 	* go/net/cgo_bsd.go: Don't refer to C.int.

Thanks.

Committed.

Ian

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-20 18:26   ` Rainer Orth
@ 2011-05-24 23:33     ` Ian Lance Taylor
  2011-05-25  0:24     ` Ian Lance Taylor
  1 sibling, 0 replies; 15+ messages in thread
From: Ian Lance Taylor @ 2011-05-24 23:33 UTC (permalink / raw)
  To: Rainer Orth; +Cc: gcc-patches, gofrontend-dev

Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> 2011-05-20  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
>
> 	libgo:
> 	* syscalls/socket_irix.go (Addrinfo): Define.
>         Declare AI_*, EAI_* constants.

Committed.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-20 18:26   ` Rainer Orth
  2011-05-24 23:33     ` Ian Lance Taylor
@ 2011-05-25  0:24     ` Ian Lance Taylor
  1 sibling, 0 replies; 15+ messages in thread
From: Ian Lance Taylor @ 2011-05-25  0:24 UTC (permalink / raw)
  To: Rainer Orth; +Cc: gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 335 bytes --]

Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> One needs to check for putenv vs. setenv and handle that in
> go-setenv.c.  I've hacked around the issue for the moment to at least
> let bootstrap succeed.

I fixed this problem like so.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 1975 bytes --]

diff -r 42dfe9ab0c96 libgo/configure.ac
--- a/libgo/configure.ac	Tue May 24 14:44:49 2011 -0700
+++ b/libgo/configure.ac	Tue May 24 15:01:29 2011 -0700
@@ -431,7 +431,7 @@
 AC_CHECK_HEADERS(sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h)
 AM_CONDITIONAL(HAVE_SYS_MMAN_H, test "$ac_cv_header_sys_mman_h" = yes)
 
-AC_CHECK_FUNCS(srandom random strerror_r strsignal wait4 mincore)
+AC_CHECK_FUNCS(srandom random strerror_r strsignal wait4 mincore setenv)
 AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes)
 AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes)
 
diff -r 42dfe9ab0c96 libgo/runtime/go-setenv.c
--- a/libgo/runtime/go-setenv.c	Tue May 24 14:44:49 2011 -0700
+++ b/libgo/runtime/go-setenv.c	Tue May 24 15:01:29 2011 -0700
@@ -4,6 +4,8 @@
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "config.h"
+
 #include <stddef.h>
 #include <stdlib.h>
 
@@ -25,24 +27,38 @@
 
   ks = k.__data;
   kn = NULL;
+  vs = v.__data;
+  vn = NULL;
+
+#ifdef HAVE_SETENV
+
   if (ks[k.__length] != 0)
     {
       kn = __go_alloc (k.__length + 1);
-      __builtin_memcpy (kn, k.__data, k.__length);
+      __builtin_memcpy (kn, ks, k.__length);
       ks = kn;
     }
 
-  vs = v.__data;
-  vn = NULL;
   if (vs[v.__length] != 0)
     {
       vn = __go_alloc (v.__length + 1);
-      __builtin_memcpy (vn, v.__data, v.__length);
+      __builtin_memcpy (vn, vs, v.__length);
       vs = vn;
     }
 
   setenv ((const char *) ks, (const char *) vs, 1);
 
+#else /* !defined(HAVE_SETENV) */
+
+  kn = malloc (k.__length + v.__length + 2);
+  __builtin_memcpy (kn, ks, k.__length);
+  kn[k.__length] = '=';
+  __builtin_memcpy (kn + k.__length + 1, vs, v.__length);
+  kn[k.__length + v.__length + 1] = '\0';
+  putenv ((char *) kn);
+
+#endif /* !defined(HAVE_SETENV) */
+
   if (kn != NULL)
     __go_free (kn);
   if (vn != NULL)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-24 21:33   ` Ian Lance Taylor
@ 2011-05-25 19:11     ` Rainer Orth
  2011-05-26  6:36       ` Ian Lance Taylor
  2011-05-26  9:04       ` Ian Lance Taylor
  0 siblings, 2 replies; 15+ messages in thread
From: Rainer Orth @ 2011-05-25 19:11 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, gofrontend-dev

Ian Lance Taylor <iant@google.com> writes:

> I just committed a patch to godump.c which I think should fix this
> issue.  Let me know if it doesn't.

There are several issues now:

* While I get

// var ___iob [59+1]___FILE

  now, there's still

var __lastbuf *_FILE

  left, with commented

// type _FILE struct { _cnt int32; _ptr *uint8; _base *uint8; _flag uint8; _file
 uint8; __orientation INVALID-bit-field; __ionolock INVALID-bit-field; __seekabl
e INVALID-bit-field; __extendedfd INVALID-bit-field; __xf_nocheck INVALID-bit-fi
eld; __filler INVALID-bit-field; }

   as before.

* The amd64 sysinfo.go contains several undefined types:

sysinfo.go:2886:53: error: use of undefined type '_fpchip_state'
sysinfo.go:2886:40: error: struct field type is incomplete
sysinfo.go:2886:53: error: use of undefined type '_fpchip_state'
sysinfo.go:2887:47: error: struct field type is incomplete
sysinfo.go:2892:32: error: use of undefined type '_fxsave_state'
sysinfo.go:2892:24: error: struct field type is incomplete

type _fpu struct { fp_reg_set struct { fpchip_state _fpchip_state; }; }
type _fpregset_t struct { fp_reg_set struct { fpchip_state _fpchip_state; }; }
type __kfpu_u struct { kfpu_fx _fxsave_state; }
type _kfpu_t struct { kfpu_u __kfpu_u; kfpu_status uint32; kfpu_xstatus uint32; }

  Both types are commented, due to the use of commented _upad128_t:

// type _upad128_t struct { _q INVALID-float-80; }

// type _fpchip_state struct { cw uint16; sw uint16; fctw uint8; __fx_rsvd uint8; fop uint16; rip uint64; rdp uint64; mxcsr uint32; mxcsr_mask uint32; st [7+1]struct { fpr_16 [4+1]uint16; }; xmm [15+1]_upad128_t; __fx_ign2 [5+1]_upad128_t; status uint32; xstatus uint32; }
// type _fxsave_state struct { fx_fcw uint16; fx_fsw uint16; fx_fctw uint16; fx_fop uint16; fx_rip uint64; fx_rdp uint64; fx_mxcsr uint32; fx_mxcsr_mask uint32; fx_st [7+1]struct { fpr_16 [4+1]uint16; }; fx_xmm [15+1]_upad128_t; __fx_ign2 [5+1]_upad128_t; }

  Unfortunately, this has as ripple effect and I need to omit several
  type declarations to make the problem go away:

+  grep -v '^type _fpu' | \
+  grep -v '^type _fpregset_t' | \
+  grep -v '^type _mcontext_t' | \
+  grep -v '^type _ucontext' | \
+  grep -v '^type __kfpu_u' | \
+  grep -v '^type _kfpu_t' | \

  <sys/types.h> has

typedef union {
        long double     _q;
        uint32_t        _l[4];
} upad128_t;

  I already have to provide a _upad128_t replacement for other uses, but
  it would really help to support this directly.

With those types and __lastbuf omitted from sysinfo.go, I can
successfully bootstrap on i386-pc-solaris2.1[01].  On Solaris 11/x86,
the libgo results are clean, on Solaris 10/x86 there are still 37
failures for the amd64 multilib which I still need to debug.

Thanks.
	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-25 19:11     ` Rainer Orth
@ 2011-05-26  6:36       ` Ian Lance Taylor
  2011-05-26 11:11         ` Rainer Orth
  2011-05-26  9:04       ` Ian Lance Taylor
  1 sibling, 1 reply; 15+ messages in thread
From: Ian Lance Taylor @ 2011-05-26  6:36 UTC (permalink / raw)
  To: Rainer Orth; +Cc: gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 1221 bytes --]

Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> * While I get
>
> // var ___iob [59+1]___FILE
>
>   now, there's still
>
> var __lastbuf *_FILE
>
>   left, with commented
>
> // type _FILE struct { _cnt int32; _ptr *uint8; _base *uint8; _flag uint8; _file
>  uint8; __orientation INVALID-bit-field; __ionolock INVALID-bit-field; __seekabl
> e INVALID-bit-field; __extendedfd INVALID-bit-field; __xf_nocheck INVALID-bit-fi
> eld; __filler INVALID-bit-field; }
>
>    as before.
>
> * The amd64 sysinfo.go contains several undefined types:
>
> sysinfo.go:2886:53: error: use of undefined type '_fpchip_state'
> sysinfo.go:2886:40: error: struct field type is incomplete
> sysinfo.go:2886:53: error: use of undefined type '_fpchip_state'
> sysinfo.go:2887:47: error: struct field type is incomplete
> sysinfo.go:2892:32: error: use of undefined type '_fxsave_state'
> sysinfo.go:2892:24: error: struct field type is incomplete

This patch should fix these problems.  Bootstrapped and ran Go testsuite
on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2011-05-25  Ian Lance Taylor  <iant@google.com>

	* godump.c (go_format_type): Check for invalid type names, pointer
	target types, and struct field types.



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 3182 bytes --]

Index: gcc/godump.c
===================================================================
--- gcc/godump.c	(revision 174141)
+++ gcc/godump.c	(working copy)
@@ -532,8 +532,18 @@ go_format_type (struct godump_container 
       break;
 
     case TYPE_DECL:
-      obstack_1grow (ob, '_');
-      go_append_string (ob, DECL_NAME (type));
+      {
+	void **slot;
+
+	slot = htab_find_slot (container->invalid_hash,
+			       IDENTIFIER_POINTER (DECL_NAME (type)),
+			       NO_INSERT);
+	if (slot != NULL)
+	  ret = false;
+
+	obstack_1grow (ob, '_');
+	go_append_string (ob, DECL_NAME (type));
+      }
       break;
 
     case INTEGER_TYPE:
@@ -604,31 +614,28 @@ go_format_type (struct godump_container 
 		      == FUNCTION_TYPE))))
         {
 	  tree name;
+	  void **slot;
 
 	  name = TYPE_NAME (TREE_TYPE (type));
-	  if (TREE_CODE (name) == IDENTIFIER_NODE)
-	    {
-	      obstack_grow (ob, "*_", 2);
-	      go_append_string (ob, name);
+	  if (TREE_CODE (name) == TYPE_DECL)
+	    name = DECL_NAME (name);
 
-	      /* The pointer here can be used without the struct or
-		 union definition.  So this struct or union is a a
-		 potential dummy type.  */
-	      if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
-		pointer_set_insert (container->pot_dummy_types,
-				    IDENTIFIER_POINTER (name));
+	  slot = htab_find_slot (container->invalid_hash,
+				 IDENTIFIER_POINTER (name), NO_INSERT);
+	  if (slot != NULL)
+	    ret = false;
 
-	      return ret;
-	    }
-	  else if (TREE_CODE (name) == TYPE_DECL)
-	    {
-	      obstack_grow (ob, "*_", 2);
-	      go_append_string (ob, DECL_NAME (name));
-	      if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
-		pointer_set_insert (container->pot_dummy_types,
-				    IDENTIFIER_POINTER (DECL_NAME (name)));
-	      return ret;
-	    }
+	  obstack_grow (ob, "*_", 2);
+	  go_append_string (ob, name);
+
+	  /* The pointer here can be used without the struct or union
+	     definition.  So this struct or union is a potential dummy
+	     type.  */
+	  if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
+	    pointer_set_insert (container->pot_dummy_types,
+				IDENTIFIER_POINTER (name));
+
+	  return ret;
         }
       if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
 	obstack_grow (ob, "func", 4);
@@ -716,17 +723,21 @@ go_format_type (struct godump_container 
 			    && (TREE_CODE (TREE_TYPE (TREE_TYPE (field)))
                                 == FUNCTION_TYPE))))
 		  {
-		    tree name = TYPE_NAME (TREE_TYPE (field));
-		    if (TREE_CODE (name) == IDENTIFIER_NODE)
-		      {
-			obstack_1grow (ob, '_');
-			go_append_string (ob, name);
-		      }
-		    else if (TREE_CODE (name) == TYPE_DECL)
-		      {
-			obstack_1grow (ob, '_');
-			go_append_string (ob, DECL_NAME (name));
-		      }
+		    tree name;
+		    void **slot;
+
+		    name = TYPE_NAME (TREE_TYPE (field));
+		    if (TREE_CODE (name) == TYPE_DECL)
+		      name = DECL_NAME (name);
+
+		    slot = htab_find_slot (container->invalid_hash,
+					   IDENTIFIER_POINTER (name),
+					   NO_INSERT);
+		    if (slot != NULL)
+		      ret = false;
+
+		    obstack_1grow (ob, '_');
+		    go_append_string (ob, name);
 		  }
 		else
 		  {

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-25 19:11     ` Rainer Orth
  2011-05-26  6:36       ` Ian Lance Taylor
@ 2011-05-26  9:04       ` Ian Lance Taylor
  1 sibling, 0 replies; 15+ messages in thread
From: Ian Lance Taylor @ 2011-05-26  9:04 UTC (permalink / raw)
  To: Rainer Orth; +Cc: gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 713 bytes --]

Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

>   <sys/types.h> has
>
> typedef union {
>         long double     _q;
>         uint32_t        _l[4];
> } upad128_t;
>
>   I already have to provide a _upad128_t replacement for other uses, but
>   it would really help to support this directly.

I think I have fixed this problem with this patch.  This patch looks for
the first field in a union which has a usable type, increasing the
chances of making the union usable in Go.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2011-05-25  Ian Lance Taylor  <iant@google.com>

	* godump.c (go_format_type): Output the first field with a usable
	Go type, if any.



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 2164 bytes --]

Index: gcc/godump.c
===================================================================
--- gcc/godump.c	(revision 174253)
+++ gcc/godump.c	(working copy)
@@ -685,6 +685,17 @@ go_format_type (struct godump_container 
 	     field != NULL_TREE;
 	     field = TREE_CHAIN (field))
 	  {
+	    struct obstack hold_type_obstack;
+	    bool field_ok;
+
+	    if (TREE_CODE (type) == UNION_TYPE)
+	      {
+		hold_type_obstack = container->type_obstack;
+		obstack_init (&container->type_obstack);
+	      }
+
+	    field_ok = true;
+
 	    if (DECL_NAME (field) == NULL)
 	      {
 		char buf[100];
@@ -711,7 +722,7 @@ go_format_type (struct godump_container 
 	    if (DECL_BIT_FIELD (field))
 	      {
 		obstack_grow (ob, "INVALID-bit-field", 17);
-		ret = false;
+		field_ok = false;
 	      }
 	    else
               {
@@ -734,7 +745,7 @@ go_format_type (struct godump_container 
 					   IDENTIFIER_POINTER (name),
 					   NO_INSERT);
 		    if (slot != NULL)
-		      ret = false;
+		      field_ok = false;
 
 		    obstack_1grow (ob, '_');
 		    go_append_string (ob, name);
@@ -743,15 +754,39 @@ go_format_type (struct godump_container 
 		  {
 		    if (!go_format_type (container, TREE_TYPE (field), true,
 					 false))
-		      ret = false;
+		      field_ok = false;
 		  }
               }
 	    obstack_grow (ob, "; ", 2);
 
-	    /* Only output the first field of a union, and hope for
-	       the best.  */
+	    /* Only output the first successful field of a union, and
+	       hope for the best.  */
 	    if (TREE_CODE (type) == UNION_TYPE)
-	      break;
+	      {
+		if (!field_ok && TREE_CHAIN (field) == NULL_TREE)
+		  {
+		    field_ok = true;
+		    ret = false;
+		  }
+		if (field_ok)
+		  {
+		    unsigned int sz;
+
+		    sz = obstack_object_size (&container->type_obstack);
+		    obstack_grow (&hold_type_obstack,
+				  obstack_base (&container->type_obstack),
+				  sz);
+		  }
+		obstack_free (&container->type_obstack, NULL);
+		container->type_obstack = hold_type_obstack;
+		if (field_ok)
+		  break;
+	      }
+	    else
+	      {
+		if (!field_ok)
+		  ret = false;
+	      }
 	  }
 	obstack_1grow (ob, '}');
       }

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Go patch committed: Update to current Go library
  2011-05-26  6:36       ` Ian Lance Taylor
@ 2011-05-26 11:11         ` Rainer Orth
  0 siblings, 0 replies; 15+ messages in thread
From: Rainer Orth @ 2011-05-26 11:11 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, gofrontend-dev

Ian Lance Taylor <iant@google.com> writes:

> Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:
>
>> * While I get
>>
>> // var ___iob [59+1]___FILE
>>
>>   now, there's still
>>
>> var __lastbuf *_FILE
>>
>>   left, with commented
>>
>> // type _FILE struct { _cnt int32; _ptr *uint8; _base *uint8; _flag uint8; _file
>>  uint8; __orientation INVALID-bit-field; __ionolock INVALID-bit-field; __seekabl
>> e INVALID-bit-field; __extendedfd INVALID-bit-field; __xf_nocheck INVALID-bit-fi
>> eld; __filler INVALID-bit-field; }
>>
>>    as before.
>>
>> * The amd64 sysinfo.go contains several undefined types:
>>
>> sysinfo.go:2886:53: error: use of undefined type '_fpchip_state'
>> sysinfo.go:2886:40: error: struct field type is incomplete
>> sysinfo.go:2886:53: error: use of undefined type '_fpchip_state'
>> sysinfo.go:2887:47: error: struct field type is incomplete
>> sysinfo.go:2892:32: error: use of undefined type '_fxsave_state'
>> sysinfo.go:2892:24: error: struct field type is incomplete
>
> This patch should fix these problems.  Bootstrapped and ran Go testsuite
> on x86_64-unknown-linux-gnu.  Committed to mainline.

Yes, I could just successfully bootstrap mainline on i386-pc-solaris2.10
without any workarounds.

Thanks.
	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2011-05-26 10:43 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-20  9:44 Go patch committed: Update to current Go library Ian Lance Taylor
2011-05-20 14:18 ` Rainer Orth
2011-05-20 14:37   ` Jakub Jelinek
2011-05-20 19:31     ` Ian Lance Taylor
2011-05-20 18:09   ` Rainer Orth
2011-05-24 22:41     ` Ian Lance Taylor
2011-05-20 18:26   ` Rainer Orth
2011-05-24 23:33     ` Ian Lance Taylor
2011-05-25  0:24     ` Ian Lance Taylor
2011-05-24 21:33   ` Ian Lance Taylor
2011-05-25 19:11     ` Rainer Orth
2011-05-26  6:36       ` Ian Lance Taylor
2011-05-26 11:11         ` Rainer Orth
2011-05-26  9:04       ` Ian Lance Taylor
2011-05-24 22:01   ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).