diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2017-07-25 22:54:23 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2017-07-25 22:54:23 +0000 |
commit | 08327dfa73c3cc2daf15a0c4405ae1bcfa940ef3 (patch) | |
tree | d45157c11b96e49a3175cd09161923fe1925180c /gcc/go | |
parent | c2830789baaa2c6fd41adcc2c02a757ab59c843c (diff) | |
download | gcc-08327dfa73c3cc2daf15a0c4405ae1bcfa940ef3.zip gcc-08327dfa73c3cc2daf15a0c4405ae1bcfa940ef3.tar.gz gcc-08327dfa73c3cc2daf15a0c4405ae1bcfa940ef3.tar.bz2 |
compiler: clean up unresolved placeholders for pointer types
Add a new helper routine Type::finish_pointer_types that walks through
the pointer type cache and looks for placeholder types that may have
been created at some point before conversion of named types, and
invokes Type::finish_backend() on said placeholders. This is needed
to handle cases where the compiler manufactures a pointer type as part
of lowering, then a placeholder is created for it due to a call to
Type::backend_type_size(), but there is no explicit reference to the
type in user code.
Reviewed-on: https://go-review.googlesource.com/51131
From-SVN: r250548
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 40 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.h | 9 |
4 files changed, 49 insertions, 4 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 4c0b827..78905fe 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -e1bd9ea4dc16e228164c92a12c5229ddf20f2b50 +61ce3b80ab20cb1f16960c1784bc0937abaa440a The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index a9d72ff..ca4b454 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -4824,6 +4824,8 @@ Gogo::convert_named_types() Runtime::convert_types(this); this->named_types_are_converted_ = true; + + Type::finish_pointer_types(this); } // Convert all names types in a set of bindings. diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index ca5f512..91d6091 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -5516,14 +5516,17 @@ Pointer_type::do_import(Import* imp) return Type::make_pointer_type(to); } +// Cache of pointer types. Key is "to" type, value is pointer type +// that points to key. + +Type::Pointer_type_table Type::pointer_types; + // Make a pointer type. Pointer_type* Type::make_pointer_type(Type* to_type) { - typedef Unordered_map(Type*, Pointer_type*) Hashtable; - static Hashtable pointer_types; - Hashtable::const_iterator p = pointer_types.find(to_type); + Pointer_type_table::const_iterator p = pointer_types.find(to_type); if (p != pointer_types.end()) return p->second; Pointer_type* ret = new Pointer_type(to_type); @@ -5531,6 +5534,37 @@ Type::make_pointer_type(Type* to_type) return ret; } +// This helper is invoked immediately after named types have been +// converted, to clean up any unresolved pointer types remaining in +// the pointer type cache. +// +// The motivation for this routine: occasionally the compiler creates +// some specific pointer type as part of a lowering operation (ex: +// pointer-to-void), then Type::backend_type_size() is invoked on the +// type (which creates a Btype placeholder for it), that placeholder +// passed somewhere along the line to the back end, but since there is +// no reference to the type in user code, there is never a call to +// Type::finish_backend for the type (hence the Btype remains as an +// unresolved placeholder). Calling this routine will clean up such +// instances. + +void +Type::finish_pointer_types(Gogo* gogo) +{ + for (Pointer_type_table::const_iterator i = pointer_types.begin(); + i != pointer_types.end(); + ++i) + { + Pointer_type* pt = i->second; + Type_btypes::iterator tbti = Type::type_btypes.find(pt); + if (tbti != Type::type_btypes.end() && tbti->second.is_placeholder) + { + pt->finish_backend(gogo, tbti->second.btype); + tbti->second.is_placeholder = false; + } + } +} + // The nil type. We use a special type for nil because it is not the // same as any other type. In C term nil has type void*, but there is // no such type in Go. diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index aeb04d6..f659f38 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -504,6 +504,9 @@ class Type static Pointer_type* make_pointer_type(Type*); + static void + finish_pointer_types(Gogo* gogo); + static Type* make_nil_type(); @@ -1341,6 +1344,12 @@ class Type static Type_functions type_functions_table; + // Cache for reusing existing pointer types; maps from pointed-to-type + // to pointer type. + typedef Unordered_map(Type*, Pointer_type*) Pointer_type_table; + + static Pointer_type_table pointer_types; + // The type classification. Type_classification classification_; // The backend representation of the type, once it has been |