diff mbox

[gccgo] Prohibit conversions from string to named []byte

Message ID mcraao2efrf.fsf@google.com
State New
Headers show

Commit Message

Ian Lance Taylor Aug. 31, 2010, 7:36 p.m. UTC
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
diff mbox

Patch

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)
 }