This ensures there are no dangling references to AST members that have been freed, either explcitly or by the garbage collector.
gcc/d/ChangeLog: * d-builtins.cc (build_frontend_type): Restore builtin_converted_decls length on conversion failure. --- gcc/d/d-builtins.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc index ff2a5776dc5..9db46c0c5ca 100644 --- a/gcc/d/d-builtins.cc +++ b/gcc/d/d-builtins.cc @@ -80,7 +80,8 @@ build_frontend_type (tree type) mod |= MODshared; /* If we've seen the type before, re-use the converted decl. */ - for (size_t i = 0; i < builtin_converted_decls.length (); ++i) + unsigned saved_builtin_decls_length = builtin_converted_decls.length (); + for (size_t i = 0; i < saved_builtin_decls_length; ++i) { tree t = builtin_converted_decls[i].ctype; if (TYPE_MAIN_VARIANT (t) == TYPE_MAIN_VARIANT (type)) @@ -249,6 +250,9 @@ build_frontend_type (tree type) Type *ftype = build_frontend_type (TREE_TYPE (field)); if (!ftype) { + /* Drop any field types that got cached before the conversion + of this record type failed. */ + builtin_converted_decls.truncate (saved_builtin_decls_length); delete sdecl->members; return NULL; } @@ -307,6 +311,9 @@ build_frontend_type (tree type) Type *targ = build_frontend_type (argtype); if (!targ) { + /* Drop any parameter types that got cached before the + conversion of this function type failed. */ + builtin_converted_decls.truncate (saved_builtin_decls_length); delete args; return NULL; } -- 2.30.2