From patchwork Wed Nov 27 23:01:21 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Hudson-Doyle X-Patchwork-Id: 294688 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 6F0D82C00AA for ; Thu, 28 Nov 2013 10:01:44 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type; q=dns; s=default; b=JEoiRKnap5uHO5oNb8XXzyKSuutAKaa/5LbCj6WzuIG7XQG46Y uxHIF/ZUTb+nw4svri+AfvqfkGi6OXvV0vzf1pSxqSSqflqmRWcNHALTNsxdMvdK g1VyArvd0qwmJ7YdcuKUGFUqrVQ42J6FgMKdr2n0EfUVPhaCsS9bohMwU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type; s= default; bh=AtrnH9kGl+kQMcTirfmXMlW5FuE=; b=YjOmNv8ZOs58q6FWXkvs TOXT0uWln/OYOm71D2PijZtPBo6fubRpPmjsClEQv/6PwHYo5xm1PUaSDK4tGmc/ IVQSx22c9qQ7gnyryQsAPXymd8CtwUQaLTELUi45ADGXjfs8gKEBG7DFb+24DTxE toD3/KL8g928J2QxvwfZc6M= Received: (qmail 28802 invoked by alias); 27 Nov 2013 23:01:35 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 28792 invoked by uid 89); 27 Nov 2013 23:01:34 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.8 required=5.0 tests=AWL, BAYES_50, RDNS_NONE autolearn=no version=3.3.2 X-HELO: youngberry.canonical.com Received: from Unknown (HELO youngberry.canonical.com) (91.189.89.112) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 27 Nov 2013 23:01:33 +0000 Received: from [120.136.5.22] (helo=narsil) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1Vlo6n-00064U-Pm; Wed, 27 Nov 2013 23:01:26 +0000 Received: by narsil (Postfix, from userid 1000) id 487FA521F0C; Thu, 28 Nov 2013 12:01:21 +1300 (NZDT) From: Michael Hudson-Doyle To: gcc-patches Cc: Ian Lance Taylor Subject: Backport reflect.Call fixes to 4.8 branch User-Agent: Notmuch/0.17~rc1+4~g7f07bfd (http://notmuchmail.org) Emacs/24.3.50.2 (x86_64-pc-linux-gnu) Date: Thu, 28 Nov 2013 12:01:21 +1300 Message-ID: <874n6xh2ke.fsf@canonical.com> MIME-Version: 1.0 This patch brings the recent fix for calling a function or method that takes or returns an empty struct via reflection to the 4.8 branch. Cheers, mwh diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index 526f09b..eecc459 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -1430,6 +1430,46 @@ func TestFunc(t *testing.T) { } } +type emptyStruct struct{} + +type nonEmptyStruct struct { + member int +} + +func returnEmpty() emptyStruct { + return emptyStruct{} +} + +func takesEmpty(e emptyStruct) { +} + +func returnNonEmpty(i int) nonEmptyStruct { + return nonEmptyStruct{member: i} +} + +func takesNonEmpty(n nonEmptyStruct) int { + return n.member +} + +func TestCallWithStruct(t *testing.T) { + r := ValueOf(returnEmpty).Call([]Value{}) + if len(r) != 1 || r[0].Type() != TypeOf(emptyStruct{}) { + t.Errorf("returning empty struct returned %s instead", r) + } + r = ValueOf(takesEmpty).Call([]Value{ValueOf(emptyStruct{})}) + if len(r) != 0 { + t.Errorf("takesEmpty returned values: %s", r) + } + r = ValueOf(returnNonEmpty).Call([]Value{ValueOf(42)}) + if len(r) != 1 || r[0].Type() != TypeOf(nonEmptyStruct{}) || r[0].Field(0).Int() != 42 { + t.Errorf("returnNonEmpty returned %s", r) + } + r = ValueOf(takesNonEmpty).Call([]Value{ValueOf(nonEmptyStruct{member: 42})}) + if len(r) != 1 || r[0].Type() != TypeOf(1) || r[0].Int() != 42 { + t.Errorf("takesNonEmpty returned %s", r) + } +} + func TestMakeFunc(t *testing.T) { switch runtime.GOARCH { case "amd64", "386": diff --git a/libgo/runtime/go-reflect-call.c b/libgo/runtime/go-reflect-call.c index 5cf3707..12bd0d7 100644 --- a/libgo/runtime/go-reflect-call.c +++ b/libgo/runtime/go-reflect-call.c @@ -98,9 +98,12 @@ go_struct_to_ffi (const struct __go_struct_type *descriptor) const struct __go_struct_field *fields; int i; + field_count = descriptor->__fields.__count; + if (field_count == 0) { + return &ffi_type_void; + } ret = (ffi_type *) __go_alloc (sizeof (ffi_type)); ret->type = FFI_TYPE_STRUCT; - field_count = descriptor->__fields.__count; fields = (const struct __go_struct_field *) descriptor->__fields.__values; ret->elements = (ffi_type **) __go_alloc ((field_count + 1) * sizeof (ffi_type *));