The functions unsafe.Sizeof, unsafe.Alignof, and unsafe.Offsetof are supported to return uintptr. The Go frontend was incorrectly having them return int. This patch fixes the problem. This uncovered a couple of problems in the gccgo-specific part of libgo, which are also fixed by this patch. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline and 4.7 branch.
Ian
diff -r 854ced9f1d72 go/expressions.cc --- a/go/expressions.cc Wed Mar 28 16:18:42 2012 -0700 +++ b/go/expressions.cc Wed Mar 28 20:50:30 2012 -0700 @@ -7091,7 +7091,8 @@ else go_unreachable(); - nc->set_unsigned_long(NULL, static_cast<unsigned long>(ret)); + nc->set_unsigned_long(Type::lookup_integer_type("uintptr"), + static_cast<unsigned long>(ret)); return true; } else if (this->code_ == BUILTIN_OFFSETOF) @@ -7113,7 +7114,8 @@ farg->field_index(), &offset)) return false; - nc->set_unsigned_long(NULL, static_cast<unsigned long>(offset)); + nc->set_unsigned_long(Type::lookup_integer_type("uintptr"), + static_cast<unsigned long>(offset)); return true; } else if (this->code_ == BUILTIN_REAL || this->code_ == BUILTIN_IMAG) @@ -7246,10 +7248,12 @@ case BUILTIN_CAP: case BUILTIN_COPY: case BUILTIN_LEN: + return Type::lookup_integer_type("int"); + case BUILTIN_ALIGNOF: case BUILTIN_OFFSETOF: case BUILTIN_SIZEOF: - return Type::lookup_integer_type("int"); + return Type::lookup_integer_type("uintptr"); case BUILTIN_CLOSE: case BUILTIN_DELETE: @@ -8078,8 +8082,8 @@ go_assert(saw_errors()); return error_mark_node; } - Type* int_type = Type::lookup_integer_type("int"); - tree type = type_to_tree(int_type->get_backend(gogo)); + Type* uintptr_type = Type::lookup_integer_type("uintptr"); + tree type = type_to_tree(uintptr_type->get_backend(gogo)); return build_int_cst(type, val); } diff -r 854ced9f1d72 go/unsafe.cc --- a/go/unsafe.cc Wed Mar 28 16:18:42 2012 -0700 +++ b/go/unsafe.cc Wed Mar 28 20:50:30 2012 -0700 @@ -57,11 +57,11 @@ if (add_to_globals) this->add_named_type(pointer_type); - Type* int_type = this->lookup_global("int")->type_value(); + Type* uintptr_type = Type::lookup_integer_type("uintptr"); // Sizeof. Typed_identifier_list* results = new Typed_identifier_list; - results->push_back(Typed_identifier("", int_type, bloc)); + results->push_back(Typed_identifier("", uintptr_type, bloc)); Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc); fntype->set_is_builtin(); no = bindings->add_function_declaration("Sizeof", package, fntype, bloc); @@ -70,7 +70,7 @@ // Offsetof. results = new Typed_identifier_list; - results->push_back(Typed_identifier("", int_type, bloc)); + results->push_back(Typed_identifier("", uintptr_type, bloc)); fntype = Type::make_function_type(NULL, NULL, results, bloc); fntype->set_is_varargs(); fntype->set_is_builtin(); @@ -80,7 +80,7 @@ // Alignof. results = new Typed_identifier_list; - results->push_back(Typed_identifier("", int_type, bloc)); + results->push_back(Typed_identifier("", uintptr_type, bloc)); fntype = Type::make_function_type(NULL, NULL, results, bloc); fntype->set_is_varargs(); fntype->set_is_builtin(); diff -r 854ced9f1d72 libgo/go/os/dir.go --- a/libgo/go/os/dir.go Wed Mar 28 16:18:42 2012 -0700 +++ b/libgo/go/os/dir.go Wed Mar 28 20:50:30 2012 -0700 @@ -34,7 +34,7 @@ func (file *File) readdirnames(n int) (names []string, err error) { if elen == 0 { var dummy syscall.Dirent - elen = (unsafe.Offsetof(dummy.Name) + + elen = (int(unsafe.Offsetof(dummy.Name)) + libc_pathconf(syscall.StringBytePtr(file.name), syscall.PC_NAME_MAX) + 1) } diff -r 854ced9f1d72 libgo/go/syscall/libcall_posix.go --- a/libgo/go/syscall/libcall_posix.go Wed Mar 28 16:18:42 2012 -0700 +++ b/libgo/go/syscall/libcall_posix.go Wed Mar 28 20:50:30 2012 -0700 @@ -138,7 +138,7 @@ //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) //select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) int -const nfdbits = unsafe.Sizeof(fds_bits_type) * 8 +const nfdbits = int(unsafe.Sizeof(fds_bits_type) * 8) type FdSet struct { Bits [(FD_SETSIZE + nfdbits - 1) / nfdbits]fds_bits_type