Commit 8b6b3806 authored by Russ Cox's avatar Russ Cox

stricter rules for assignment.

when assigning a multifield object
(structs or arrays of structs) they
must not contain any fields that could
not be assigned individually.

R=ken
OCL=29192
CL=29194
parent b9159722
......@@ -2046,14 +2046,59 @@ loop:
goto loop;
}
/*
* do the export rules allow writing to this type?
* cannot be implicitly assigning to any type with
* an unavailable field.
*/
int
exportasok(Type *t)
{
Type *f;
Sym *s;
if(t == T)
return 1;
switch(t->etype) {
default:
// most types can't contain others; they're all fine.
break;
case TSTRUCT:
for(f=t->type; f; f=f->down) {
if(f->etype != TFIELD)
fatal("structas: not field");
s = f->sym;
// s == nil doesn't happen for embedded fields (they get the type symbol).
// it only happens for fields in a ... struct.
if(s != nil && !exportname(s->name) && strcmp(package, s->package) != 0) {
yyerror("implicit assignment of %T field '%s'", t, s->name);
return 0;
}
if(!exportasok(f->type))
return 0;
}
break;
case TARRAY:
if(t->bound < 0) // slices are pointers; that's fine
break;
if(!exportasok(t->type))
return 0;
break;
}
return 1;
}
/*
* can we assign var of type src to var of type dst
*/
int
ascompat(Type *dst, Type *src)
{
if(eqtype(dst, src))
if(eqtype(dst, src)) {
exportasok(src);
return 1;
}
if(dst == T || src == T)
return 0;
......
// errchk $G $D/$F.go
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "sync"
type T struct {
int;
sync.Mutex;
}
func main() {
{
var x, y sync.Mutex;
x = y; // ERROR "assignment.*Mutex"
}
{
var x, y T;
x = y; // ERROR "assignment.*Mutex"
}
{
var x, y [2]sync.Mutex;
x = y; // ERROR "assignment.*Mutex"
}
{
var x, y [2]T;
x = y; // ERROR "assignment.*Mutex"
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment