From patchwork Mon Aug 8 19:53:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 656952 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3s7Sm34KSpz9t0m for ; Tue, 9 Aug 2016 05:54:11 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=LPlp7E1s; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=W7B92mJ1h00llq+cD31pbJmdflz8gcIz5sJgPMzPI76vMH pZ/zXpesefDF/rf6Fo7TCkDlifEH7JdKpmLh8iQSE8HOfqmyqi/MvccpwwO+4Urm /Xt8wU3lqvokBsnrf+mGpNrsCbJxqSaxi6q8fqkp+79jaiedsQMtsDXo/FChQ= 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 :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=/Cu3bfiRSUbLuJrg4WRjZHBBnug=; b=LPlp7E1syA8N6Hs5vLsF 8hR2W8yO9/vdoaUcx4OVBMwN74+jGxUDz99Dv4El/RE2OScik/aE4S/cluEIasB9 F4FiaSBSwbFlUK4B/UrhuATi6YpRlm8X6oinMX0PpJ52w6uyn226wi93af3phuCr gSpjLEeMFxujaivVmA3Pm0w= Received: (qmail 122747 invoked by alias); 8 Aug 2016 19:54:03 -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 122685 invoked by uid 89); 8 Aug 2016 19:54:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 spammy=MERGE, gofrontend, sk:eeeeff3, gogcccc X-HELO: mail-io0-f174.google.com Received: from mail-io0-f174.google.com (HELO mail-io0-f174.google.com) (209.85.223.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Mon, 08 Aug 2016 19:53:52 +0000 Received: by mail-io0-f174.google.com with SMTP id m101so367467053ioi.2 for ; Mon, 08 Aug 2016 12:53:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=CIBTT5c5zMYn0YDVm/xujVNrz6wJLOaqxBo1UO5CR6M=; b=HWFwnvbrQcj5IdSt8ihHTxc/AbmijnpSTYKCqfIZuQ43bPkk+qWscTwqxH331/WZE4 9JeIdSS/VYKEoy7vdRS0LRJrLCyA7Zy2SdqZTJyfL7hG4J9VAw1KZhBZDvqQuGnRaACo zpr3fjAiKYoqNAKRFY23Z7zjH2ffOy92urCFAnd4KG3iLFHt9VcIXX3JCXsaJJ4VS5Bt kzU13HVPM0uKw3kvlA49W1OAXX/d8DqvFkXVmAdy3g2hNznYnQezaBsoijpBzKFmhsg4 WNG3ObLVWzbRjhg3rDdPvYN0AQbMa2GdfmsnwkUx3H2+BKwyUHznVwWegiVtjaFwVZb4 uSLQ== X-Gm-Message-State: AEkoous9m994NE/m9wqb6eNRfxMg7gJmJrpW4sqBsB9jx5YEywuMMzNvma2jQjf4RaB1LyxCp9VZUt5X6p+gmA== X-Received: by 10.107.155.82 with SMTP id d79mr103051303ioe.36.1470686030176; Mon, 08 Aug 2016 12:53:50 -0700 (PDT) MIME-Version: 1.0 Received: by 10.79.35.199 with HTTP; Mon, 8 Aug 2016 12:53:49 -0700 (PDT) From: Ian Lance Taylor Date: Mon, 8 Aug 2016 12:53:49 -0700 Message-ID: Subject: libgo patch committed: treat functions that return zero bytes as returning void To: gcc-patches , "gofrontend-dev@googlegroups.com" PR 72814 is a bug that is due to a mismatch between libffi and the code being called when the code returns a zero-sized struct. libffi can not represent a zero-sized struct, so the Go runtime creates a libffi type that uses a one-byte struct. This technique fails on 32-bit SPARC, where the calling convention for a zero-sized struct is different than the calling convention for a one-byte struct; calls to the latter function are followed by an unimp instruction, calls to the former are not. This patch fixes the problem by treating functions that return zero result byte as though they actually return void. The change is to the GCC interface and the libffi interface used by the gofrontend. For this patch bootstrapped on x86_64-pc-linux-gnu and sparc-sun-solaris. Ran the full Go testsuite on x86_64-pc-linux-gnu and the reflect package tests on sparc-sun-solaris. Committed to mainline. Ian 2016-08-08 Ian Lance Taylor PR go/72814 * go-gcc.cc (Gcc_backend::function_type): If the return type is zero bytes, treat the function as returning void. (return_statement): If the return type is zero bytes, don't actually return any values. Index: gcc/go/go-gcc.cc =================================================================== --- gcc/go/go-gcc.cc (revision 239179) +++ gcc/go/go-gcc.cc (working copy) @@ -953,6 +953,14 @@ Gcc_backend::function_type(const Btyped_ if (result == error_mark_node) return this->error_type(); + // The libffi library can not represent a zero-sized object. To + // avoid causing confusion on 32-bit SPARC, we treat a function that + // returns a zero-sized value as returning void. That should do no + // harm since there is no actual value to be returned. See + // https://gcc.gnu.org/PR72814 for details. + if (result != void_type_node && int_size_in_bytes(result) == 0) + result = void_type_node; + tree fntype = build_function_type(result, args); if (fntype == error_mark_node) return this->error_type(); @@ -2127,6 +2135,27 @@ Gcc_backend::return_statement(Bfunction* if (result == error_mark_node) return this->error_statement(); + // If the result size is zero bytes, we have set the function type + // to have a result type of void, so don't return anything. + // See the function_type method. + if (int_size_in_bytes(TREE_TYPE(result)) == 0) + { + tree stmt_list = NULL_TREE; + for (std::vector::const_iterator p = vals.begin(); + p != vals.end(); + p++) + { + tree val = (*p)->get_tree(); + if (val == error_mark_node) + return this->error_statement(); + append_to_statement_list(val, &stmt_list); + } + tree ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, + void_type_node, NULL_TREE); + append_to_statement_list(ret, &stmt_list); + return this->make_statement(stmt_list); + } + tree ret; if (vals.empty()) ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node, Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 239225) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -eeeeff3e3dd6c09aaefdf13cce99a5beff47a095 +5e4c16d4fea39835e16f17c3d2b2e85f5c81d815 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: libgo/runtime/go-ffi.c =================================================================== --- libgo/runtime/go-ffi.c (revision 238653) +++ libgo/runtime/go-ffi.c (working copy) @@ -288,6 +288,17 @@ go_func_return_ffi (const struct __go_fu types = (const struct __go_type_descriptor **) func->__out.__values; + // We compile a function that returns a zero-sized value as though + // it returns void. This works around a problem in libffi: it can't + // represent a zero-sized value. + for (i = 0; i < count; ++i) + { + if (types[i]->__size > 0) + break; + } + if (i == count) + return &ffi_type_void; + if (count == 1) return go_type_to_ffi (types[0]);