compiler: Don't check for hidden fields on struct assignments.

From-SVN: r182143
This commit is contained in:
Ian Lance Taylor 2011-12-08 23:27:33 +00:00
parent 0ee1c847f7
commit 1fbbc69cdf
8 changed files with 48 additions and 106 deletions

View File

@ -12817,7 +12817,22 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
Location location = this->location();
Struct_type* st = type->struct_type();
if (this->vals_ == NULL || !this->has_keys_)
return new Struct_construction_expression(type, this->vals_, location);
{
if (this->vals_ != NULL && !this->vals_->empty())
{
std::string reason;
if (type->has_hidden_fields(NULL, &reason))
{
if (reason.empty())
error_at(this->location(),
"implicit assignment of hidden field");
else
error_at(this->location(), "%s", reason.c_str());
}
}
return new Struct_construction_expression(type, this->vals_, location);
}
size_t field_count = st->field_count();
std::vector<Expression*> vals(field_count);
@ -12964,6 +12979,26 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
return Expression::make_error(location);
}
if (type->named_type() != NULL
&& type->named_type()->named_object()->package() != NULL
&& Gogo::is_hidden_name(sf->field_name()))
error_at(name_expr->location(),
"assignment of unexported field %qs in %qs literal",
Gogo::message_name(sf->field_name()).c_str(),
type->named_type()->message_name().c_str());
else
{
std::string reason;
if (sf->type()->has_hidden_fields(NULL, &reason))
{
if (reason.empty())
error_at(name_expr->location(),
"implicit assignment of hidden field");
else
error_at(name_expr->location(), "%s", reason.c_str());
}
}
vals[index] = val;
}

View File

@ -605,7 +605,7 @@ Type::are_assignable_check_hidden(const Type* lhs, const Type* rhs,
bool
Type::are_assignable(const Type* lhs, const Type* rhs, std::string* reason)
{
return Type::are_assignable_check_hidden(lhs, rhs, true, reason);
return Type::are_assignable_check_hidden(lhs, rhs, false, reason);
}
// Like are_assignable but don't check for hidden fields.

View File

@ -16,38 +16,38 @@ type T struct {
func main() {
{
var x, y sync.Mutex
x = y // ERROR "assignment.*Mutex"
x = y // ok
_ = x
}
{
var x, y T
x = y // ERROR "assignment.*Mutex"
x = y // ok
_ = x
}
{
var x, y [2]sync.Mutex
x = y // ERROR "assignment.*Mutex"
x = y // ok
_ = x
}
{
var x, y [2]T
x = y // ERROR "assignment.*Mutex"
x = y // ok
_ = x
}
{
x := sync.Mutex{0, 0} // ERROR "assignment.*Mutex"
x := sync.Mutex{0, 0} // ERROR "assignment.*Mutex"
_ = x
}
{
x := sync.Mutex{key: 0} // ERROR "(unknown|assignment).*Mutex"
x := sync.Mutex{key: 0} // ERROR "(unknown|assignment).*Mutex"
_ = x
}
{
x := &sync.Mutex{} // ok
var y sync.Mutex // ok
y = *x // ERROR "assignment.*Mutex"
*x = y // ERROR "assignment.*Mutex"
x := &sync.Mutex{} // ok
var y sync.Mutex // ok
y = *x // ok
*x = y // ok
_ = x
_ = y
}
}
}

View File

@ -1,9 +0,0 @@
// 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 x
type T struct { x, Y int }
func (t T) M()

View File

@ -1,31 +0,0 @@
// 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 y
import "./x"
func f() {
ok := new(x.T);
var ok1 x.T;
ok2 := &ok1;
ok3 := &x.T{};
ok4 := &x.T{Y:2};
_ = x.T{};
_ = x.T{Y:2};
ok1.M();
bad1 := *ok; // ERROR "assignment.*T"
bad2 := ok1; // ERROR "assignment.*T"
*ok4 = ok1; // ERROR "assignment.*T"
*ok4 = *ok2; // ERROR "assignment.*T"
ok1 = *ok4; // ERROR "assignment.*T"
_ = bad1;
_ = bad2;
_ = ok4;
_ = ok3;
_ = ok2;
_ = ok1;
_ = ok;
}

View File

@ -1,7 +0,0 @@
// $G $D/$F.dir/x.go && errchk $G $D/$F.dir/y.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.
ignored

View File

@ -1,20 +0,0 @@
// errchk $G $D/$F.go
// Copyright 2010 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 p
import (
"bytes"
"fmt"
)
type t int
func main() {
_ = t.bar // ERROR "no method"
var b bytes.Buffer
fmt.Print(b) // ERROR "implicit assignment"
}

View File

@ -1,26 +0,0 @@
// errchk $G $D/$F.go
// Copyright 2011 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.
// issue 1910
// error on wrong line
package main
import "container/list"
type Painting struct {
fragments list.List // private
}
func (p Painting) Foo() {
for e := p.fragments; e.Front() != nil; { // ERROR "unexported field|hidden field"
}
}
// from comment 4 of issue 1910
type Foo interface {
Run(a int) (a int) // ERROR "a redeclared|redefinition|previous"
}