re PR go/67968 (go1: internal compiler error: in write_specific_type_functions, at go/gofrontend/types.cc:1812)

PR go/67968
    compiler: Traverse types of call expressions.
    
    https://gcc.gnu.org/PR67968 provides a test case that causes a gccgo
    crash on valid code.  The compiler failed to build the hash and equality
    functions required for a type descriptor.  The descriptor is for an
    unnamed type that is being returned by a function imported from a
    different package.  The unnamed type is being implicitly converted to an
    interface type by a return statement.  The fix is to ensure that the
    type of a call expression is always traversed.
    
    Test case sent out for the master testsuite as
    https://golang.org/cl/16532 .

From-SVN: r229642
This commit is contained in:
Ian Lance Taylor 2015-11-01 20:46:04 +00:00
parent 2bbee501a3
commit 2e4e655cf3
2 changed files with 11 additions and 1 deletions

View File

@ -1,4 +1,4 @@
1c1f226662a6c84eae83f8aaec3d4503e70be843 65ff1d5fb581717229e5c02796d719671a1e8628
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.

View File

@ -8608,6 +8608,16 @@ Builtin_call_expression::do_export(Export* exp) const
int int
Call_expression::do_traverse(Traverse* traverse) Call_expression::do_traverse(Traverse* traverse)
{ {
// If we are calling a function in a different package that returns
// an unnamed type, this may be the only chance we get to traverse
// that type. We don't traverse this->type_ because it may be a
// Call_multiple_result_type that will just lead back here.
if (this->type_ != NULL && !this->type_->is_error_type())
{
Function_type *fntype = this->get_function_type();
if (fntype != NULL && Type::traverse(fntype, traverse) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
}
if (Expression::traverse(&this->fn_, traverse) == TRAVERSE_EXIT) if (Expression::traverse(&this->fn_, traverse) == TRAVERSE_EXIT)
return TRAVERSE_EXIT; return TRAVERSE_EXIT;
if (this->args_ != NULL) if (this->args_ != NULL)