mirror of git://gcc.gnu.org/git/gcc.git
compiler: fix crashes on cyclic var/type references
This patch fixes type traversal to avoid compiler crashes for test
cases where a type T includes an expression that refers back to the
type without actually explicitly mentioning T. Examples include
var x [uintptr(unsafe.Sizeof(&x))]byte
var a [len(a)]int
The fix involves expanding the set of types that the traversal code
"remembers" (to avoid cycles) to include array types, and introducing an
additional guard in Builtin_call_expression::do_is_constant to catch
cyclic type constructs.
Fixes golang/go#25299
Fixes golang/go#25679
Fixes golang/go#25315
Fixes golang/go#25680
Reviewed-on: https://go-review.googlesource.com/115796
From-SVN: r261168
This commit is contained in:
parent
e68086c432
commit
f0ebf6e322
|
|
@ -1,4 +1,4 @@
|
||||||
79eca4fd642724d89e9bec8f79889451f6632a46
|
8e74a218e11ef6eaaf7014a3ad1cd0b13359c607
|
||||||
|
|
||||||
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.
|
||||||
|
|
|
||||||
|
|
@ -8061,9 +8061,13 @@ Builtin_call_expression::do_is_constant() const
|
||||||
arg_type = arg_type->points_to();
|
arg_type = arg_type->points_to();
|
||||||
|
|
||||||
if (arg_type->array_type() != NULL
|
if (arg_type->array_type() != NULL
|
||||||
&& arg_type->array_type()->length() != NULL
|
&& arg_type->array_type()->length() != NULL)
|
||||||
&& Builtin_call_expression::array_len_is_constant(arg))
|
{
|
||||||
return true;
|
this->seen_ = true;
|
||||||
|
bool ret = Builtin_call_expression::array_len_is_constant(arg);
|
||||||
|
this->seen_ = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
|
if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8258,8 +8258,16 @@ Traverse::remember_type(const Type* type)
|
||||||
// We mostly only have to remember named types. But it turns out
|
// We mostly only have to remember named types. But it turns out
|
||||||
// that an interface type can refer to itself without using a name
|
// that an interface type can refer to itself without using a name
|
||||||
// by relying on interface inheritance, as in
|
// by relying on interface inheritance, as in
|
||||||
// type I interface { F() interface{I} }
|
//
|
||||||
|
// type I interface { F() interface{I} }
|
||||||
|
//
|
||||||
|
// Similarly it is possible for array types to refer to themselves
|
||||||
|
// without a name, e.g.
|
||||||
|
//
|
||||||
|
// var x [uintptr(unsafe.Sizeof(&x))]byte
|
||||||
|
//
|
||||||
if (type->classification() != Type::TYPE_NAMED
|
if (type->classification() != Type::TYPE_NAMED
|
||||||
|
&& type->classification() != Type::TYPE_ARRAY
|
||||||
&& type->classification() != Type::TYPE_INTERFACE)
|
&& type->classification() != Type::TYPE_INTERFACE)
|
||||||
return false;
|
return false;
|
||||||
if (this->types_seen_ == NULL)
|
if (this->types_seen_ == NULL)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue