#include "convert.h"
#include "output.h"
#include "diagnostic.h"
-#include "rtl.h"
#ifndef ENABLE_BUILD_WITH_CXX
}
if (this->init_fn_name_.empty())
{
gcc_assert(this->package_ != NULL);
- if (this->package_name() == "main")
+ if (this->is_main_package())
{
// Use a name which the runtime knows.
this->init_fn_name_ = "__go_init_main";
void
Gogo::init_imports(tree* init_stmt_list)
{
- gcc_assert(this->package_name() == "main");
+ gcc_assert(this->is_main_package());
if (this->imported_init_fns_.empty())
return;
void_type_node,
build_pointer_type(root_list_type),
build_fold_addr_expr(decl));
- append_to_statement_list(call, init_stmt_list);
+ if (call != error_mark_node)
+ append_to_statement_list(call, init_stmt_list);
}
// Build the decl for the initialization function.
{
// Make sure that we thought we needed an initialization function,
// as otherwise we will not have reported it in the export data.
- gcc_assert(this->package_name() == "main" || this->need_init_fn_);
+ gcc_assert(this->is_main_package() || this->need_init_fn_);
if (fndecl == NULL_TREE)
fndecl = this->initialization_function_decl();
void
Gogo::write_globals()
{
+ this->convert_named_types();
+ this->build_interface_method_tables();
+
Bindings* bindings = this->current_bindings();
size_t count = bindings->size_definitions();
tree init_fndecl = NULL_TREE;
tree init_stmt_list = NULL_TREE;
- if (this->package_name() == "main")
+ if (this->is_main_package())
this->init_imports(&init_stmt_list);
// A list of variable initializations.
pop_cfun();
}
- if (var_init_tree != NULL_TREE)
+ if (var_init_tree != NULL_TREE && var_init_tree != error_mark_node)
{
if (no->var_value()->init() == NULL
&& !no->var_value()->has_pre_init())
// This will be called if this package is imported.
if (init_stmt_list != NULL_TREE
|| this->need_init_fn_
- || this->package_name() == "main")
+ || this->is_main_package())
this->write_initialization_function(init_fndecl, init_stmt_list);
// Pass everything back to the middle-end.
- if (this->imported_unsafe_)
- {
- // Importing the "unsafe" package automatically disables TBAA.
- flag_strict_aliasing = false;
-
- // This is a real hack. init_varasm_once has already grabbed an
- // alias set, which we don't want when we aren't going strict
- // aliasing. We reinitialize to make it do it again. FIXME.
- init_varasm_once();
- }
-
wrapup_global_declarations(vec, count);
cgraph_finalize_compilation_unit();
Translate_context context(gogo, function, NULL, NULL_TREE);
tree block_tree = this->preinit_->get_tree(&context);
+ if (block_tree == error_mark_node)
+ return error_mark_node;
gcc_assert(TREE_CODE(block_tree) == BIND_EXPR);
tree statements = BIND_EXPR_BODY(block_tree);
- while (TREE_CODE(statements) == TRY_FINALLY_EXPR
- || TREE_CODE(statements) == TRY_CATCH_EXPR)
+ while (statements != NULL_TREE
+ && (TREE_CODE(statements) == TRY_FINALLY_EXPR
+ || TREE_CODE(statements) == TRY_CATCH_EXPR))
statements = TREE_OPERAND(statements, 0);
// It's possible to have pre-init statements without an initializer
if (this->init_ != NULL)
{
tree rhs_tree = this->init_->get_tree(&context);
+ if (rhs_tree == error_mark_node)
+ return error_mark_node;
if (var_decl == NULL_TREE)
append_to_statement_list(rhs_tree, &statements);
else
this->init_->type(),
rhs_tree,
this->location());
+ if (val == error_mark_node)
+ return error_mark_node;
tree set = fold_build2_loc(this->location(), MODIFY_EXPR,
void_type_node, var_decl, val);
append_to_statement_list(set, &statements);
this->fndecl_ = decl;
- gcc_assert(no->package() == NULL);
- if (this->enclosing_ != NULL || Gogo::is_thunk(no))
+ if (no->package() != NULL)
+ ;
+ else if (this->enclosing_ != NULL || Gogo::is_thunk(no))
;
else if (Gogo::unpack_hidden_name(no->name()) == "init"
&& !this->type_->is_method())
;
else if (Gogo::unpack_hidden_name(no->name()) == "main"
- && gogo->package_name() == "main")
+ && gogo->is_main_package())
TREE_PUBLIC(decl) = 1;
// Methods have to be public even if they are hidden because
// they can be pulled into type descriptors when using
void_type_node,
ptr_type_node,
this->defer_stack(end_loc));
- append_to_statement_list(call, &stmt_list);
+ if (call != error_mark_node)
+ append_to_statement_list(call, &stmt_list);
tree retval = this->return_value(gogo, named_function, end_loc, &stmt_list);
tree set;
void_type_node,
ptr_type_node,
this->defer_stack(end_loc));
- TREE_NOTHROW(undefer_fndecl) = 0;
+ if (undefer_fndecl != NULL_TREE)
+ TREE_NOTHROW(undefer_fndecl) = 0;
tree defer = Gogo::call_builtin(&check_fndecl,
end_loc,
Map_descriptors::iterator p = ins.first;
if (!ins.second)
{
+ if (p->second == error_mark_node)
+ return error_mark_node;
gcc_assert(p->second != NULL_TREE && DECL_P(p->second));
return build_fold_addr_expr(p->second);
}
"__val",
valtype->get_tree(this));
if (map_entry_type == error_mark_node)
- return error_mark_node;
+ {
+ p->second = error_mark_node;
+ return error_mark_node;
+ }
tree map_entry_key_field = DECL_CHAIN(TYPE_FIELDS(map_entry_type));
gcc_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(map_entry_key_field)),
DECL_INITIAL(decl) = constructor;
- if (type_descriptor_location == TYPE_DESCRIPTOR_COMMON)
+ if (type_descriptor_location == TYPE_DESCRIPTOR_DEFINED)
+ TREE_PUBLIC(decl) = 1;
+ else
{
+ gcc_assert(type_descriptor_location == TYPE_DESCRIPTOR_COMMON);
make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
resolve_unique_section(decl, 1, 0);
}
- else
- {
-#ifdef OBJECT_FORMAT_ELF
- // Give the decl protected visibility. This avoids out-of-range
- // references with shared libraries with the x86_64 small model
- // when the type descriptor gets a COPY reloc into the main
- // executable. There is no need to have unique pointers to type
- // descriptors, as the runtime code compares reflection strings
- // if necessary.
- DECL_VISIBILITY(decl) = VISIBILITY_PROTECTED;
- DECL_VISIBILITY_SPECIFIED(decl) = 1;
-#endif
-
- TREE_PUBLIC(decl) = 1;
- }
rest_of_decl_compilation(decl, 1, 0);
}
// definition of the table. Otherwise it is a comdat table which
// may be defined in multiple packages.
if (has_hidden_methods)
- {
-#ifdef OBJECT_FORMAT_ELF
- // Give the decl protected visibility. This avoids out-of-range
- // references with shared libraries with the x86_64 small model
- // when the table gets a COPY reloc into the main executable.
- DECL_VISIBILITY(decl) = VISIBILITY_PROTECTED;
- DECL_VISIBILITY_SPECIFIED(decl) = 1;
-#endif
-
- TREE_PUBLIC(decl) = 1;
- }
+ TREE_PUBLIC(decl) = 1;
else
{
make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
types[i] = va_arg(ap, tree);
args[i] = va_arg(ap, tree);
if (types[i] == error_mark_node || args[i] == error_mark_node)
- return error_mark_node;
+ {
+ delete[] types;
+ delete[] args;
+ return error_mark_node;
+ }
}
va_end(ap);
void_type_node,
integer_type_node,
build_int_cst(integer_type_node, code));
+ if (ret == error_mark_node)
+ return error_mark_node;
// The runtime error function panics and does not return.
TREE_NOTHROW(runtime_error_fndecl) = 0;
TREE_THIS_VOLATILE(runtime_error_fndecl) = 1;
Gogo::send_on_channel(tree channel, tree val, bool blocking, bool for_select,
source_location location)
{
+ if (channel == error_mark_node || val == error_mark_node)
+ return error_mark_node;
+
if (int_size_in_bytes(TREE_TYPE(val)) <= 8
&& !AGGREGATE_TYPE_P(TREE_TYPE(val))
&& !FLOAT_TYPE_P(TREE_TYPE(val)))
(for_select
? boolean_true_node
: boolean_false_node));
+ if (ret == error_mark_node)
+ return error_mark_node;
// This can panic if there are too many operations on a
// closed channel.
TREE_NOTHROW(send_small_fndecl) = 0;
channel,
uint64_type_node,
val);
+ if (ret == error_mark_node)
+ return error_mark_node;
// This can panic if there are too many operations on a
// closed channel.
TREE_NOTHROW(send_nonblocking_small_fndecl) = 0;
(for_select
? boolean_true_node
: boolean_false_node));
+ if (call == error_mark_node)
+ return error_mark_node;
// This can panic if there are too many operations on a
// closed channel.
TREE_NOTHROW(send_big_fndecl) = 0;
channel,
ptr_type_node,
val);
+ if (call == error_mark_node)
+ return error_mark_node;
// This can panic if there are too many operations on a
// closed channel.
TREE_NOTHROW(send_nonblocking_big_fndecl) = 0;
Gogo::receive_from_channel(tree type_tree, tree channel, bool for_select,
source_location location)
{
+ if (type_tree == error_mark_node || channel == error_mark_node)
+ return error_mark_node;
+
if (int_size_in_bytes(type_tree) <= 8
&& !AGGREGATE_TYPE_P(type_tree)
&& !FLOAT_TYPE_P(type_tree))
(for_select
? boolean_true_node
: boolean_false_node));
+ if (call == error_mark_node)
+ return error_mark_node;
// This can panic if there are too many operations on a closed
// channel.
TREE_NOTHROW(receive_small_fndecl) = 0;
(for_select
? boolean_true_node
: boolean_false_node));
+ if (call == error_mark_node)
+ return error_mark_node;
// This can panic if there are too many operations on a closed
// channel.
TREE_NOTHROW(receive_big_fndecl) = 0;
ptr_type_node,
fold_convert_loc(location, ptr_type_node,
closure));
+ if (x == error_mark_node)
+ return error_mark_node;
x = save_expr(x);