From patchwork Tue Aug 31 19:36:20 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: 63314 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 311F7B7171 for ; Wed, 1 Sep 2010 05:36:37 +1000 (EST) Received: (qmail 6842 invoked by alias); 31 Aug 2010 19:36:35 -0000 Received: (qmail 6828 invoked by uid 22791); 31 Aug 2010 19:36:34 -0000 X-SWARE-Spam-Status: No, hits=-1.0 required=5.0 tests=AWL, BAYES_40, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, SPF_HELO_PASS, TW_CC, 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) (74.125.121.35) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 31 Aug 2010 19:36:28 +0000 Received: from hpaq7.eem.corp.google.com (hpaq7.eem.corp.google.com [172.25.149.7]) by smtp-out.google.com with ESMTP id o7VJaPsW006855 for ; Tue, 31 Aug 2010 12:36:25 -0700 Received: from gyd10 (gyd10.prod.google.com [10.243.49.202]) by hpaq7.eem.corp.google.com with ESMTP id o7VJa8pO007957 for ; Tue, 31 Aug 2010 12:36:24 -0700 Received: by gyd10 with SMTP id 10so3831660gyd.1 for ; Tue, 31 Aug 2010 12:36:24 -0700 (PDT) Received: by 10.150.146.2 with SMTP id t2mr97016ybd.116.1283283384190; Tue, 31 Aug 2010 12:36:24 -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 t16sm4522024ybm.22.2010.08.31.12.36.22 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 31 Aug 2010 12:36:23 -0700 (PDT) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: [gccgo] Prohibit conversions from string to named []byte User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Date: Tue, 31 Aug 2010 12:36:20 -0700 Message-ID: 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 A followon to the type compatibility fixes. Go permits converting from string to []byte or []int, but it does not permit converting to a named form of those types. This patch implements that. Committed to gccgo branch. Ian Index: gcc/go/types.cc =================================================================== --- gcc/go/types.cc (revision 163681) +++ gcc/go/types.cc (working copy) @@ -605,7 +605,7 @@ Type::are_convertible(const Type* lhs, c { if (rhs->integer_type() != NULL) return true; - if (rhs->is_open_array_type()) + if (rhs->is_open_array_type() && rhs->named_type() == NULL) { const Type* e = rhs->array_type()->element_type()->forwarded(); if (e->integer_type() != NULL @@ -616,7 +616,9 @@ Type::are_convertible(const Type* lhs, c } // A string may be converted to []byte or []int. - if (rhs->is_string_type() && lhs->is_open_array_type()) + if (rhs->is_string_type() + && lhs->is_open_array_type() + && lhs->named_type() == NULL) { const Type* e = lhs->array_type()->element_type()->forwarded(); if (e->integer_type() != NULL Index: gcc/go/expressions.cc =================================================================== --- gcc/go/expressions.cc (revision 163689) +++ gcc/go/expressions.cc (working copy) @@ -2959,7 +2959,7 @@ Type_conversion_expression::do_lower(Gog mpfr_clear(imag); } - if (type->is_open_array_type()) + if (type->is_open_array_type() && type->named_type() == NULL) { Type* element_type = type->array_type()->element_type()->forwarded(); bool is_byte = element_type == Type::lookup_integer_type("uint8"); Index: gcc/testsuite/go.test/test/named.go =================================================================== --- gcc/testsuite/go.test/test/named.go (revision 163682) +++ gcc/testsuite/go.test/test/named.go (working copy) @@ -20,13 +20,13 @@ type String string // Calling these functions checks at compile time that the argument // can be converted implicitly to (used as) the given type. -func asArray(Array) {} -func asBool(Bool) {} -func asChan(Chan) {} -func asFloat(Float) {} -func asInt(Int) {} -func asMap(Map) {} -func asSlice(Slice) {} +func asArray(Array) {} +func asBool(Bool) {} +func asChan(Chan) {} +func asFloat(Float) {} +func asInt(Int) {} +func asMap(Map) {} +func asSlice(Slice) {} func asString(String) {} func (Map) M() {} @@ -35,247 +35,247 @@ func (Map) M() {} // These functions check at run time that the default type // (in the absence of any implicit conversion hints) // is the given type. -func isArray(x interface{}) { _ = x.(Array) } -func isBool(x interface{}) { _ = x.(Bool) } -func isChan(x interface{}) { _ = x.(Chan) } -func isFloat(x interface{}) { _ = x.(Float) } -func isInt(x interface{}) { _ = x.(Int) } -func isMap(x interface{}) { _ = x.(Map) } -func isSlice(x interface{}) { _ = x.(Slice) } +func isArray(x interface{}) { _ = x.(Array) } +func isBool(x interface{}) { _ = x.(Bool) } +func isChan(x interface{}) { _ = x.(Chan) } +func isFloat(x interface{}) { _ = x.(Float) } +func isInt(x interface{}) { _ = x.(Int) } +func isMap(x interface{}) { _ = x.(Map) } +func isSlice(x interface{}) { _ = x.(Slice) } func isString(x interface{}) { _ = x.(String) } func main() { var ( - a Array; - b Bool = true; - c Chan = make(Chan); - f Float = 1; - i Int = 1; - m Map = make(Map); - slice Slice = make(Slice, 10); - str String = "hello"; + a Array + b Bool = true + c Chan = make(Chan) + f Float = 1 + i Int = 1 + m Map = make(Map) + slice Slice = make(Slice, 10) + str String = "hello" ) - asArray(a); - isArray(a); - asArray(*&a); - isArray(*&a); - asArray(Array{}); - isArray(Array{}); - - asBool(b); - isBool(b); - asBool(!b); - isBool(!b); - asBool(true); - asBool(*&b); - isBool(*&b); - asBool(Bool(true)); - isBool(Bool(true)); - - asChan(c); - isChan(c); - asChan(make(Chan)); - isChan(make(Chan)); - asChan(*&c); - isChan(*&c); - asChan(Chan(nil)); - isChan(Chan(nil)); - - asFloat(f); - isFloat(f); - asFloat(-f); - isFloat(-f); - asFloat(+f); - isFloat(+f); - asFloat(f+1); - isFloat(f+1); - asFloat(1+f); - isFloat(1+f); - asFloat(f+f); - isFloat(f+f); - f++; - f+=2; - asFloat(f-1); - isFloat(f-1); - asFloat(1-f); - isFloat(1-f); - asFloat(f-f); - isFloat(f-f); - f--; - f-=2; - asFloat(f*2.5); - isFloat(f*2.5); - asFloat(2.5*f); - isFloat(2.5*f); - asFloat(f*f); - isFloat(f*f); - f*=4; - asFloat(f/2.5); - isFloat(f/2.5); - asFloat(2.5/f); - isFloat(2.5/f); - asFloat(f/f); - isFloat(f/f); - f/=4; - asFloat(f); - isFloat(f); - f = 5; - asFloat(*&f); - isFloat(*&f); - asFloat(234); - asFloat(Float(234)); - isFloat(Float(234)); - asFloat(1.2); - asFloat(Float(i)); - isFloat(Float(i)); - - asInt(i); - isInt(i); - asInt(-i); - isInt(-i); - asInt(^i); - isInt(^i); - asInt(+i); - isInt(+i); - asInt(i+1); - isInt(i+1); - asInt(1+i); - isInt(1+i); - asInt(i+i); - isInt(i+i); - i++; - i+=1; - asInt(i-1); - isInt(i-1); - asInt(1-i); - isInt(1-i); - asInt(i-i); - isInt(i-i); - i--; - i-=1; - asInt(i*2); - isInt(i*2); - asInt(2*i); - isInt(2*i); - asInt(i*i); - isInt(i*i); - i*=2; - asInt(i/5); - isInt(i/5); - asInt(5/i); - isInt(5/i); - asInt(i/i); - isInt(i/i); - i/=2; - asInt(i%5); - isInt(i%5); - asInt(5%i); - isInt(5%i); - asInt(i%i); - isInt(i%i); - i%=2; - asInt(i&5); - isInt(i&5); - asInt(5&i); - isInt(5&i); - asInt(i&i); - isInt(i&i); - i&=2; - asInt(i&^5); - isInt(i&^5); - asInt(5&^i); - isInt(5&^i); - asInt(i&^i); - isInt(i&^i); - i&^=2; - asInt(i|5); - isInt(i|5); - asInt(5|i); - isInt(5|i); - asInt(i|i); - isInt(i|i); - i|=2; - asInt(i^5); - isInt(i^5); - asInt(5^i); - isInt(5^i); - asInt(i^i); - isInt(i^i); - i^=2; - asInt(i<<4); - isInt(i<<4); - i<<=2; - asInt(i>>4); - isInt(i>>4); - i>>=2; - asInt(i); - isInt(i); - asInt(0); - asInt(Int(0)); - isInt(Int(0)); - i = 10; - asInt(*&i); - isInt(*&i); - asInt(23); - asInt(Int(f)); - isInt(Int(f)); - - asMap(m); - isMap(m); - asMap(nil); - m = nil; - asMap(make(Map)); - isMap(make(Map)); - asMap(*&m); - isMap(*&m); - asMap(Map(nil)); - isMap(Map(nil)); - asMap(Map{}); - isMap(Map{}); - - asSlice(slice); - isSlice(slice); - asSlice(make(Slice, 5)); - isSlice(make(Slice, 5)); - asSlice([]byte{1,2,3}); - asSlice([]byte{1,2,3}[0:2]); - asSlice(slice[0:4]); - isSlice(slice[0:4]); - asSlice(slice[3:8]); - isSlice(slice[3:8]); - asSlice(nil); - asSlice(Slice(nil)); - isSlice(Slice(nil)); - slice = nil; - asSlice(Slice{1,2,3}); - isSlice(Slice{1,2,3}); - asSlice(Slice{}); - isSlice(Slice{}); - asSlice(*&slice); - isSlice(*&slice); - - asString(str); - isString(str); - asString(str+"a"); - isString(str+"a"); - asString("a"+str); - isString("a"+str); - asString(str+str); - isString(str+str); - str += "a"; - str += str; - asString(String('a')); - isString(String('a')); - asString(String(slice)); - isString(String(slice)); - asString(String([]byte(nil))); - isString(String([]byte(nil))); - asString("hello"); - asString(String("hello")); - isString(String("hello")); - str = "hello"; - isString(str); - asString(*&str); - isString(*&str); + asArray(a) + isArray(a) + asArray(*&a) + isArray(*&a) + asArray(Array{}) + isArray(Array{}) + + asBool(b) + isBool(b) + asBool(!b) + isBool(!b) + asBool(true) + asBool(*&b) + isBool(*&b) + asBool(Bool(true)) + isBool(Bool(true)) + + asChan(c) + isChan(c) + asChan(make(Chan)) + isChan(make(Chan)) + asChan(*&c) + isChan(*&c) + asChan(Chan(nil)) + isChan(Chan(nil)) + + asFloat(f) + isFloat(f) + asFloat(-f) + isFloat(-f) + asFloat(+f) + isFloat(+f) + asFloat(f + 1) + isFloat(f + 1) + asFloat(1 + f) + isFloat(1 + f) + asFloat(f + f) + isFloat(f + f) + f++ + f += 2 + asFloat(f - 1) + isFloat(f - 1) + asFloat(1 - f) + isFloat(1 - f) + asFloat(f - f) + isFloat(f - f) + f-- + f -= 2 + asFloat(f * 2.5) + isFloat(f * 2.5) + asFloat(2.5 * f) + isFloat(2.5 * f) + asFloat(f * f) + isFloat(f * f) + f *= 4 + asFloat(f / 2.5) + isFloat(f / 2.5) + asFloat(2.5 / f) + isFloat(2.5 / f) + asFloat(f / f) + isFloat(f / f) + f /= 4 + asFloat(f) + isFloat(f) + f = 5 + asFloat(*&f) + isFloat(*&f) + asFloat(234) + asFloat(Float(234)) + isFloat(Float(234)) + asFloat(1.2) + asFloat(Float(i)) + isFloat(Float(i)) + + asInt(i) + isInt(i) + asInt(-i) + isInt(-i) + asInt(^i) + isInt(^i) + asInt(+i) + isInt(+i) + asInt(i + 1) + isInt(i + 1) + asInt(1 + i) + isInt(1 + i) + asInt(i + i) + isInt(i + i) + i++ + i += 1 + asInt(i - 1) + isInt(i - 1) + asInt(1 - i) + isInt(1 - i) + asInt(i - i) + isInt(i - i) + i-- + i -= 1 + asInt(i * 2) + isInt(i * 2) + asInt(2 * i) + isInt(2 * i) + asInt(i * i) + isInt(i * i) + i *= 2 + asInt(i / 5) + isInt(i / 5) + asInt(5 / i) + isInt(5 / i) + asInt(i / i) + isInt(i / i) + i /= 2 + asInt(i % 5) + isInt(i % 5) + asInt(5 % i) + isInt(5 % i) + asInt(i % i) + isInt(i % i) + i %= 2 + asInt(i & 5) + isInt(i & 5) + asInt(5 & i) + isInt(5 & i) + asInt(i & i) + isInt(i & i) + i &= 2 + asInt(i &^ 5) + isInt(i &^ 5) + asInt(5 &^ i) + isInt(5 &^ i) + asInt(i &^ i) + isInt(i &^ i) + i &^= 2 + asInt(i | 5) + isInt(i | 5) + asInt(5 | i) + isInt(5 | i) + asInt(i | i) + isInt(i | i) + i |= 2 + asInt(i ^ 5) + isInt(i ^ 5) + asInt(5 ^ i) + isInt(5 ^ i) + asInt(i ^ i) + isInt(i ^ i) + i ^= 2 + asInt(i << 4) + isInt(i << 4) + i <<= 2 + asInt(i >> 4) + isInt(i >> 4) + i >>= 2 + asInt(i) + isInt(i) + asInt(0) + asInt(Int(0)) + isInt(Int(0)) + i = 10 + asInt(*&i) + isInt(*&i) + asInt(23) + asInt(Int(f)) + isInt(Int(f)) + + asMap(m) + isMap(m) + asMap(nil) + m = nil + asMap(make(Map)) + isMap(make(Map)) + asMap(*&m) + isMap(*&m) + asMap(Map(nil)) + isMap(Map(nil)) + asMap(Map{}) + isMap(Map{}) + + asSlice(slice) + isSlice(slice) + asSlice(make(Slice, 5)) + isSlice(make(Slice, 5)) + asSlice([]byte{1, 2, 3}) + asSlice([]byte{1, 2, 3}[0:2]) + asSlice(slice[0:4]) + isSlice(slice[0:4]) + asSlice(slice[3:8]) + isSlice(slice[3:8]) + asSlice(nil) + asSlice(Slice(nil)) + isSlice(Slice(nil)) + slice = nil + asSlice(Slice{1, 2, 3}) + isSlice(Slice{1, 2, 3}) + asSlice(Slice{}) + isSlice(Slice{}) + asSlice(*&slice) + isSlice(*&slice) + + asString(str) + isString(str) + asString(str + "a") + isString(str + "a") + asString("a" + str) + isString("a" + str) + asString(str + str) + isString(str + str) + str += "a" + str += str + asString(String('a')) + isString(String('a')) + asString(String([]byte(slice))) + isString(String([]byte(slice))) + asString(String([]byte(nil))) + isString(String([]byte(nil))) + asString("hello") + asString(String("hello")) + isString(String("hello")) + str = "hello" + isString(str) + asString(*&str) + isString(*&str) }