From patchwork Fri Mar 1 12:57:19 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 224330 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]) by ozlabs.org (Postfix) with SMTP id 1BD802C0091 for ; Fri, 1 Mar 2013 23:57:32 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1362747453; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Date:Message-ID:Subject:From:To:Cc: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=cAJAeRi hdM6PQsCqlz0+KpRg1yU=; b=g5dn+JIvVsJwTt9ITIeky5C9PERX9vnECnOalYJ ZEBq3tzIYrkzOUHpjKQsGNZxtDvM/dUAxZrTX69OXSForcL4KmJXH5ZJUHTH6lnU /qWW5kFg6FmkiTrx0bBag+mgefH4MGEpKm3epF+ne1AUZ4DqMS5VLVKrmBW8iVUy +nLM= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:MIME-Version:X-Received:Received:Date:Message-ID:Subject:From:To:Cc:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=foF05Z2TWPKuAlXStFM5CoCkZf7iixbuTEm4kH+r4PzySqV5xJJ0erSXufdqZj TfzQbCHuwta+CdthaUOo4owJTqiWLZRdEm+eAH+GiKjXy6Vg+8abr3byo1Zc49qw TocF3E8xLHobc1NGkKB58VY0TsC2iZ7r2nKAL8VtbRSQI=; Received: (qmail 6292 invoked by alias); 1 Mar 2013 12:57:27 -0000 Received: (qmail 6281 invoked by uid 22791); 1 Mar 2013 12:57:26 -0000 X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, TW_BF X-Spam-Check-By: sourceware.org Received: from mail-oa0-f54.google.com (HELO mail-oa0-f54.google.com) (209.85.219.54) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 01 Mar 2013 12:57:19 +0000 Received: by mail-oa0-f54.google.com with SMTP id n12so5531242oag.27 for ; Fri, 01 Mar 2013 04:57:19 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.182.156.20 with SMTP id wa20mr8468929obb.59.1362142639077; Fri, 01 Mar 2013 04:57:19 -0800 (PST) Received: by 10.182.49.68 with HTTP; Fri, 1 Mar 2013 04:57:19 -0800 (PST) Date: Fri, 1 Mar 2013 13:57:19 +0100 Message-ID: Subject: [PATCH, go] Passing Complex64 and Complex128 values via reflect.Call (using libffi) introduces ABI mismatch From: Uros Bizjak To: Ian Lance Taylor Cc: gcc-patches , gofrontend-dev@googlegroups.com 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 Hello! Due to the fact that libFFI does not handle C99 _Complex arguments correctly [1], libgo passes Complex64 and Complex128 arguments via a temporary structure. However, passing parts of complex number in a structure is not the same as passing true C99 _Complex value, so this workaround introduces ABI mismatch between caller and callee. This mismatch results in wrong passed values of complex types. Fortunately all x86 ABIs tolerate this mismatch, but other targets (i.e. alpha) don't have this privilege. Attached patch disables passing of C99 _Complex arguments via FFI on all targets, other than x86 (to be on the safe side w.r.t. other targets). Hopefully, someday libffi will be extended to handle _Complex arguments in correct way. Patch was tested on x86_64-pc-linux-gnu {,-m32} and alphaev68-pc-linux-gnu. [1] http://sourceware.org/ml/libffi-discuss/2007/msg00010.html Uros. Index: runtime/go-reflect-call.c =================================================================== --- runtime/go-reflect-call.c (revision 196368) +++ runtime/go-reflect-call.c (working copy) @@ -30,7 +30,7 @@ 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)); + __attribute__ ((no_split_stack,unused)); 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 *) @@ -185,13 +185,23 @@ return &ffi_type_double; abort (); case GO_COMPLEX64: +#if defined (__i386__) || defined (__x86_64__) if (sizeof (float) == 4) return go_complex_to_ffi (&ffi_type_float); abort (); +#else + runtime_throw("the ABI does not support Complex64 type with " + "reflect.Call or runtime.SetFinalizer"); +#endif case GO_COMPLEX128: +#if defined (__i386__) || defined (__x86_64__) if (sizeof (double) == 8) return go_complex_to_ffi (&ffi_type_double); abort (); +#else + runtime_throw("the ABI does not support Complex128 type with " + "reflect.Call or runtime.SetFinalizer"); +#endif case GO_INT16: return &ffi_type_sint16; case GO_INT32: Index: go/testing/quick/quick_test.go =================================================================== --- go/testing/quick/quick_test.go (revision 196368) +++ go/testing/quick/quick_test.go (working copy) @@ -7,6 +7,7 @@ import ( "math/rand" "reflect" + "runtime" "testing" ) @@ -72,8 +73,10 @@ reportError("fBool", CheckEqual(fBool, fBool, nil), t) reportError("fFloat32", CheckEqual(fFloat32, fFloat32, nil), t) reportError("fFloat64", CheckEqual(fFloat64, fFloat64, nil), t) - reportError("fComplex64", CheckEqual(fComplex64, fComplex64, nil), t) - reportError("fComplex128", CheckEqual(fComplex128, fComplex128, nil), t) + if runtime.GOARCH == "386" || runtime.GOARCH == "amd64" { + reportError("fComplex64", CheckEqual(fComplex64, fComplex64, nil), t) + reportError("fComplex128", CheckEqual(fComplex128, fComplex128, nil), t) + } reportError("fInt16", CheckEqual(fInt16, fInt16, nil), t) reportError("fInt32", CheckEqual(fInt32, fInt32, nil), t) reportError("fInt64", CheckEqual(fInt64, fInt64, nil), t)