From patchwork Tue Aug 31 18:10:15 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 63310 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 4F4E5B710E for ; Wed, 1 Sep 2010 04:10:33 +1000 (EST) Received: (qmail 13143 invoked by alias); 31 Aug 2010 18:10:31 -0000 Received: (qmail 13129 invoked by uid 22791); 31 Aug 2010 18:10:30 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, SPF_HELO_PASS, TW_CC, TW_TM, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.44.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 31 Aug 2010 18:10:24 +0000 Received: from hpaq5.eem.corp.google.com (hpaq5.eem.corp.google.com [172.25.149.5]) by smtp-out.google.com with ESMTP id o7VIAMZT024380 for ; Tue, 31 Aug 2010 11:10:22 -0700 Received: from gxk9 (gxk9.prod.google.com [10.202.11.9]) by hpaq5.eem.corp.google.com with ESMTP id o7VI9oJm009937 for ; Tue, 31 Aug 2010 11:10:21 -0700 Received: by gxk9 with SMTP id 9so3958913gxk.0 for ; Tue, 31 Aug 2010 11:10:20 -0700 (PDT) Received: by 10.151.150.4 with SMTP id c4mr4321952ybo.25.1283278218081; Tue, 31 Aug 2010 11:10:18 -0700 (PDT) Received: from coign.google.com (dhcp-172-22-124-178.mtv.corp.google.com [172.22.124.178]) by mx.google.com with ESMTPS id e8sm9044002ibb.14.2010.08.31.11.10.16 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 31 Aug 2010 11:10:17 -0700 (PDT) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: [gccgo] Fix handling of empty select Date: Tue, 31 Aug 2010 11:10:15 -0700 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 X-System-Of-Record: true X-IsSubscribed: yes 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 An empty select in Go is supposed to block forever, which is useless but consistent. This patch fixes gccgo to do that rather than its previous behaviour of ignoring an empty select, which was also useless and was inconsistent. Committed to gccgo branch. Ian diff -r 5538a8b3dd70 go/statements.cc --- a/go/statements.cc Tue Aug 31 11:07:10 2010 -0700 +++ b/go/statements.cc Tue Aug 31 11:08:30 2010 -0700 @@ -4076,9 +4076,6 @@ Unnamed_label *break_label, source_location location) { - if (this->clauses_.empty()) - return integer_zero_node; - size_t count = this->clauses_.size(); VEC(constructor_elt, gc)* chan_init = VEC_alloc(constructor_elt, gc, count); VEC(constructor_elt, gc)* is_send_init = VEC_alloc(constructor_elt, gc, @@ -4116,10 +4113,9 @@ } gcc_assert(i == count); - if (i == 0) + if (i == 0 && default_clause != NULL) { // There is only a default clause. - gcc_assert(default_clause != NULL); gcc_assert(final_stmt_list == NULL_TREE); tree stmt_list = NULL_TREE; append_to_statement_list(default_clause->get_statements_tree(context), @@ -4128,40 +4124,56 @@ return stmt_list; } - tree index_type_tree = build_index_type(size_int(count - 1)); - tree chan_array_type_tree = build_array_type(channel_type_tree, - index_type_tree); - tree chan_constructor = build_constructor(chan_array_type_tree, chan_init); - tree chan_var = create_tmp_var(chan_array_type_tree, "CHAN"); - DECL_IGNORED_P(chan_var) = 0; - DECL_INITIAL(chan_var) = chan_constructor; - DECL_SOURCE_LOCATION(chan_var) = location; - TREE_ADDRESSABLE(chan_var) = 1; - tree decl_expr = build1(DECL_EXPR, void_type_node, chan_var); - SET_EXPR_LOCATION(decl_expr, location); - append_to_statement_list(decl_expr, &final_stmt_list); - - tree is_send_array_type_tree = build_array_type(boolean_type_node, - index_type_tree); - tree is_send_constructor = build_constructor(is_send_array_type_tree, - is_send_init); - tree is_send_var = create_tmp_var(is_send_array_type_tree, "ISSEND"); - DECL_IGNORED_P(is_send_var) = 0; - DECL_INITIAL(is_send_var) = is_send_constructor; - DECL_SOURCE_LOCATION(is_send_var) = location; - TREE_ADDRESSABLE(is_send_var) = 1; - decl_expr = build1(DECL_EXPR, void_type_node, is_send_var); - SET_EXPR_LOCATION(decl_expr, location); - append_to_statement_list(decl_expr, &final_stmt_list); - - tree pointer_chan_type_tree = build_pointer_type(channel_type_tree); - tree chans_arg = fold_convert_loc(location, pointer_chan_type_tree, - build_fold_addr_expr_loc(location, - chan_var)); + tree pointer_chan_type_tree = (channel_type_tree == NULL_TREE + ? ptr_type_node + : build_pointer_type(channel_type_tree)); + tree chans_arg; tree pointer_boolean_type_tree = build_pointer_type(boolean_type_node); - tree is_sends_arg = fold_convert_loc(location, pointer_boolean_type_tree, - build_fold_addr_expr_loc(location, - is_send_var)); + tree is_sends_arg; + + if (i == 0) + { + chans_arg = fold_convert_loc(location, pointer_chan_type_tree, + null_pointer_node); + is_sends_arg = fold_convert_loc(location, pointer_boolean_type_tree, + null_pointer_node); + } + else + { + tree index_type_tree = build_index_type(size_int(count - 1)); + tree chan_array_type_tree = build_array_type(channel_type_tree, + index_type_tree); + tree chan_constructor = build_constructor(chan_array_type_tree, + chan_init); + tree chan_var = create_tmp_var(chan_array_type_tree, "CHAN"); + DECL_IGNORED_P(chan_var) = 0; + DECL_INITIAL(chan_var) = chan_constructor; + DECL_SOURCE_LOCATION(chan_var) = location; + TREE_ADDRESSABLE(chan_var) = 1; + tree decl_expr = build1(DECL_EXPR, void_type_node, chan_var); + SET_EXPR_LOCATION(decl_expr, location); + append_to_statement_list(decl_expr, &final_stmt_list); + + tree is_send_array_type_tree = build_array_type(boolean_type_node, + index_type_tree); + tree is_send_constructor = build_constructor(is_send_array_type_tree, + is_send_init); + tree is_send_var = create_tmp_var(is_send_array_type_tree, "ISSEND"); + DECL_IGNORED_P(is_send_var) = 0; + DECL_INITIAL(is_send_var) = is_send_constructor; + DECL_SOURCE_LOCATION(is_send_var) = location; + TREE_ADDRESSABLE(is_send_var) = 1; + decl_expr = build1(DECL_EXPR, void_type_node, is_send_var); + SET_EXPR_LOCATION(decl_expr, location); + append_to_statement_list(decl_expr, &final_stmt_list); + + chans_arg = fold_convert_loc(location, pointer_chan_type_tree, + build_fold_addr_expr_loc(location, + chan_var)); + is_sends_arg = fold_convert_loc(location, pointer_boolean_type_tree, + build_fold_addr_expr_loc(location, + is_send_var)); + } static tree select_fndecl; tree call = Gogo::call_builtin(&select_fndecl,