From patchwork Wed Jan 11 23:43:48 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 135534 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 808C3B6F62 for ; Thu, 12 Jan 2012 10:44:10 +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=1326930251; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:From:To:Subject:Date:Message-ID:User-Agent: MIME-Version:Content-Type:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=8D3dgD9mS/ytEBC+B/vK9f+gH28=; b=Atvyl4klEJEJBRA utQtd88B4Jgr93q1HdJtHYq02Lepq5jJ+COCY8a0uAbTIKGQdciegGd7hxgAL9ax D0npoZJem7gvYYQ4c0nECassjMQkQvuJakOZs+38HoIjshi/Qlw80x4+NLJ77/1C K6Z25DedcWTOMCI4aBmH4flRj4CE= 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:Received:Received:Received:From:To:Subject:Date:Message-ID:User-Agent:MIME-Version:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=rEyaOh04Csf4SFM1YI5Q0ie9cbDxxZvM/+yeP0tYMrj9bxIimLucf86E/z5xnA J1Ks7gZge3OQa6a4Z+0yfnTayhbEuMKHoyUK9Ndb3QEF4+O4lfjzfn/62YVZxQf6 9m7ZtHRKdHBPPrxUUYPjMtefPLImSpaIzRSjFum9MXKzE=; Received: (qmail 21291 invoked by alias); 11 Jan 2012 23:44:07 -0000 Received: (qmail 21283 invoked by uid 22791); 11 Jan 2012 23:44:05 -0000 X-SWARE-Spam-Status: No, hits=-2.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_LOW, TW_CC, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS X-Spam-Check-By: sourceware.org Received: from mail-iy0-f175.google.com (HELO mail-iy0-f175.google.com) (209.85.210.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 11 Jan 2012 23:43:51 +0000 Received: by iafi7 with SMTP id i7so1926840iaf.20 for ; Wed, 11 Jan 2012 15:43:51 -0800 (PST) Received: by 10.50.189.137 with SMTP id gi9mr1198080igc.1.1326325431069; Wed, 11 Jan 2012 15:43:51 -0800 (PST) Received: by 10.50.189.137 with SMTP id gi9mr1198069igc.1.1326325430969; Wed, 11 Jan 2012 15:43:50 -0800 (PST) Received: from coign.google.com ([2620:0:1000:2301:f2de:f1ff:fe40:72a8]) by mx.google.com with ESMTPS id h9sm10435747ibh.11.2012.01.11.15.43.49 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 11 Jan 2012 15:43:50 -0800 (PST) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: Go patch committed: Permit converting to string to named []B Date: Wed, 11 Jan 2012 15:43:48 -0800 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 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 The Go language was tweaked to permit converting a string to a slice of the byte or rune type even if the type is given a different name. This patch implements this tweak in the gccgo frontend. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian diff -r 4a6f27be6981 go/expressions.cc --- a/go/expressions.cc Wed Jan 11 13:19:28 2012 -0800 +++ b/go/expressions.cc Wed Jan 11 15:33:40 2012 -0800 @@ -3382,9 +3382,11 @@ if (type->is_slice_type()) { Type* element_type = type->array_type()->element_type()->forwarded(); - bool is_byte = element_type == Type::lookup_integer_type("uint8"); - bool is_int = element_type == Type::lookup_integer_type("int"); - if (is_byte || is_int) + bool is_byte = (element_type->integer_type() != NULL + && element_type->integer_type()->is_byte()); + bool is_rune = (element_type->integer_type() != NULL + && element_type->integer_type()->is_rune()); + if (is_byte || is_rune) { std::string s; if (val->string_constant_value(&s)) @@ -3690,8 +3692,7 @@ tree len = a->length_tree(gogo, expr_tree); len = fold_convert_loc(this->location().gcc_location(), integer_type_node, len); - if (e->integer_type()->is_unsigned() - && e->integer_type()->bits() == 8) + if (e->integer_type()->is_byte()) { static tree byte_array_to_string_fndecl; ret = Gogo::call_builtin(&byte_array_to_string_fndecl, @@ -3706,7 +3707,7 @@ } else { - go_assert(e == Type::lookup_integer_type("int")); + go_assert(e->integer_type()->is_rune()); static tree int_array_to_string_fndecl; ret = Gogo::call_builtin(&int_array_to_string_fndecl, this->location(), @@ -3723,8 +3724,7 @@ { Type* e = type->array_type()->element_type()->forwarded(); go_assert(e->integer_type() != NULL); - if (e->integer_type()->is_unsigned() - && e->integer_type()->bits() == 8) + if (e->integer_type()->is_byte()) { tree string_to_byte_array_fndecl = NULL_TREE; ret = Gogo::call_builtin(&string_to_byte_array_fndecl, @@ -3737,7 +3737,7 @@ } else { - go_assert(e == Type::lookup_integer_type("int")); + go_assert(e->integer_type()->is_rune()); tree string_to_int_array_fndecl = NULL_TREE; ret = Gogo::call_builtin(&string_to_int_array_fndecl, this->location(), @@ -8506,19 +8506,19 @@ break; } - Type* e2; if (arg2_type->is_slice_type()) - e2 = arg2_type->array_type()->element_type(); + { + Type* e2 = arg2_type->array_type()->element_type(); + if (!Type::are_identical(e1, e2, true, NULL)) + this->report_error(_("element types must be the same")); + } else if (arg2_type->is_string_type()) - e2 = Type::lookup_integer_type("uint8"); + { + if (e1->integer_type() == NULL || !e1->integer_type()->is_byte()) + this->report_error(_("first argument must be []byte")); + } else - { - this->report_error(_("right argument must be a slice or a string")); - break; - } - - if (!Type::are_identical(e1, e2, true, NULL)) - this->report_error(_("element types must be the same")); + this->report_error(_("second argument must be slice or string")); } break; @@ -8542,7 +8542,7 @@ { const Array_type* at = args->front()->type()->array_type(); const Type* e = at->element_type()->forwarded(); - if (e == Type::lookup_integer_type("uint8")) + if (e->integer_type() != NULL && e->integer_type()->is_byte()) break; } @@ -9100,7 +9100,8 @@ tree arg2_len; tree element_size; if (arg2->type()->is_string_type() - && element_type == Type::lookup_integer_type("uint8")) + && element_type->integer_type() != NULL + && element_type->integer_type()->is_byte()) { arg2_tree = save_expr(arg2_tree); arg2_val = String_type::bytes_tree(gogo, arg2_tree); diff -r 4a6f27be6981 go/gogo.cc --- a/go/gogo.cc Wed Jan 11 13:19:28 2012 -0800 +++ b/go/gogo.cc Wed Jan 11 15:33:40 2012 -0800 @@ -88,10 +88,12 @@ // to the same Named_object. Named_object* byte_type = this->declare_type("byte", loc); byte_type->set_type_value(uint8_type); + uint8_type->integer_type()->set_is_byte(); // "rune" is an alias for "int". Named_object* rune_type = this->declare_type("rune", loc); rune_type->set_type_value(int_type); + int_type->integer_type()->set_is_rune(); this->add_named_type(Type::make_integer_type("uintptr", true, pointer_size, diff -r 4a6f27be6981 go/types.cc --- a/go/types.cc Wed Jan 11 13:19:28 2012 -0800 +++ b/go/types.cc Wed Jan 11 15:33:40 2012 -0800 @@ -767,7 +767,7 @@ if (lhs->complex_type() != NULL && rhs->complex_type() != NULL) return true; - // An integer, or []byte, or []int, may be converted to a string. + // An integer, or []byte, or []rune, may be converted to a string. if (lhs->is_string_type()) { if (rhs->integer_type() != NULL) @@ -776,19 +776,18 @@ { const Type* e = rhs->array_type()->element_type()->forwarded(); if (e->integer_type() != NULL - && (e == Type::lookup_integer_type("uint8") - || e == Type::lookup_integer_type("int"))) + && (e->integer_type()->is_byte() + || e->integer_type()->is_rune())) return true; } } - // A string may be converted to []byte or []int. + // A string may be converted to []byte or []rune. if (rhs->is_string_type() && lhs->is_slice_type()) { const Type* e = lhs->array_type()->element_type()->forwarded(); if (e->integer_type() != NULL - && (e == Type::lookup_integer_type("uint8") - || e == Type::lookup_integer_type("int"))) + && (e->integer_type()->is_byte() || e->integer_type()->is_rune())) return true; } diff -r 4a6f27be6981 go/types.h --- a/go/types.h Wed Jan 11 13:19:28 2012 -0800 +++ b/go/types.h Wed Jan 11 15:33:40 2012 -0800 @@ -1386,7 +1386,27 @@ bool is_identical(const Integer_type* t) const; - protected: + // Whether this is the type "byte" or another name for "byte". + bool + is_byte() const + { return this->is_byte_; } + + // Mark this as the "byte" type. + void + set_is_byte() + { this->is_byte_ = true; } + + // Whether this is the type "rune" or another name for "rune". + bool + is_rune() const + { return this->is_rune_; } + + // Mark this as the "rune" type. + void + set_is_rune() + { this->is_rune_ = true; } + +protected: bool do_compare_is_identity(Gogo*) const { return true; } @@ -1410,8 +1430,8 @@ Integer_type(bool is_abstract, bool is_unsigned, int bits, int runtime_type_kind) : Type(TYPE_INTEGER), - is_abstract_(is_abstract), is_unsigned_(is_unsigned), bits_(bits), - runtime_type_kind_(runtime_type_kind) + is_abstract_(is_abstract), is_unsigned_(is_unsigned), is_byte_(false), + is_rune_(false), bits_(bits), runtime_type_kind_(runtime_type_kind) { } // Map names of integer types to the types themselves. @@ -1422,6 +1442,10 @@ bool is_abstract_; // True if this is an unsigned type. bool is_unsigned_; + // True if this is the byte type. + bool is_byte_; + // True if this is the rune type. + bool is_rune_; // The number of bits. int bits_; // The runtime type code used in the type descriptor for this type.