Commit eba4ad89 by Ian Lance Taylor

Make sure variable type is determined when var initialized to var.

From-SVN: r170643
parent ba6413bd
...@@ -957,6 +957,15 @@ Var_expression::do_type() ...@@ -957,6 +957,15 @@ Var_expression::do_type()
gcc_unreachable(); gcc_unreachable();
} }
// Determine the type of a reference to a variable.
void
Var_expression::do_determine_type(const Type_context*)
{
if (this->variable_->is_variable())
this->variable_->var_value()->determine_type();
}
// Something takes the address of this variable. This means that we // Something takes the address of this variable. This means that we
// may want to move the variable onto the heap. // may want to move the variable onto the heap.
......
...@@ -915,8 +915,7 @@ class Var_expression : public Expression ...@@ -915,8 +915,7 @@ class Var_expression : public Expression
do_type(); do_type();
void void
do_determine_type(const Type_context*) do_determine_type(const Type_context*);
{ }
Expression* Expression*
do_copy() do_copy()
......
...@@ -1730,7 +1730,7 @@ Shortcuts::convert_shortcut(Block* enclosing, Expression** pshortcut) ...@@ -1730,7 +1730,7 @@ Shortcuts::convert_shortcut(Block* enclosing, Expression** pshortcut)
Block* retblock = new Block(enclosing, loc); Block* retblock = new Block(enclosing, loc);
retblock->set_end_location(loc); retblock->set_end_location(loc);
Temporary_statement* ts = Statement::make_temporary(Type::make_boolean_type(), Temporary_statement* ts = Statement::make_temporary(Type::lookup_bool_type(),
left, loc); left, loc);
retblock->add_statement(ts); retblock->add_statement(ts);
...@@ -2086,7 +2086,7 @@ Build_recover_thunks::function(Named_object* orig_no) ...@@ -2086,7 +2086,7 @@ Build_recover_thunks::function(Named_object* orig_no)
++count; ++count;
std::string can_recover_name = buf; std::string can_recover_name = buf;
new_params->push_back(Typed_identifier(can_recover_name, new_params->push_back(Typed_identifier(can_recover_name,
Type::make_boolean_type(), Type::lookup_bool_type(),
orig_fntype->location())); orig_fntype->location()));
const Typed_identifier_list* orig_results = orig_fntype->results(); const Typed_identifier_list* orig_results = orig_fntype->results();
...@@ -2222,7 +2222,7 @@ Build_recover_thunks::function(Named_object* orig_no) ...@@ -2222,7 +2222,7 @@ Build_recover_thunks::function(Named_object* orig_no)
// Add the can_recover argument to the (now) new bindings, and // Add the can_recover argument to the (now) new bindings, and
// attach it to any recover statements. // attach it to any recover statements.
Variable* can_recover_var = new Variable(Type::make_boolean_type(), NULL, Variable* can_recover_var = new Variable(Type::lookup_bool_type(), NULL,
false, true, false, location); false, true, false, location);
can_recover_no = new_bindings->add_variable(can_recover_name, NULL, can_recover_no = new_bindings->add_variable(can_recover_name, NULL,
can_recover_var); can_recover_var);
...@@ -2273,7 +2273,7 @@ Build_recover_thunks::can_recover_arg(source_location location) ...@@ -2273,7 +2273,7 @@ Build_recover_thunks::can_recover_arg(source_location location)
Typed_identifier_list* param_types = new Typed_identifier_list(); Typed_identifier_list* param_types = new Typed_identifier_list();
Type* voidptr_type = Type::make_pointer_type(Type::make_void_type()); Type* voidptr_type = Type::make_pointer_type(Type::make_void_type());
param_types->push_back(Typed_identifier("a", voidptr_type, bloc)); param_types->push_back(Typed_identifier("a", voidptr_type, bloc));
Type* boolean_type = Type::make_boolean_type(); Type* boolean_type = Type::lookup_bool_type();
Typed_identifier_list* results = new Typed_identifier_list(); Typed_identifier_list* results = new Typed_identifier_list();
results->push_back(Typed_identifier("", boolean_type, bloc)); results->push_back(Typed_identifier("", boolean_type, bloc));
Function_type* fntype = Type::make_function_type(NULL, param_types, Function_type* fntype = Type::make_function_type(NULL, param_types,
...@@ -3216,7 +3216,7 @@ Variable::Variable(Type* type, Expression* init, bool is_global, ...@@ -3216,7 +3216,7 @@ Variable::Variable(Type* type, Expression* init, bool is_global,
is_address_taken_(false), seen_(false), init_is_lowered_(false), is_address_taken_(false), seen_(false), init_is_lowered_(false),
type_from_init_tuple_(false), type_from_range_index_(false), type_from_init_tuple_(false), type_from_range_index_(false),
type_from_range_value_(false), type_from_chan_element_(false), type_from_range_value_(false), type_from_chan_element_(false),
is_type_switch_var_(false) is_type_switch_var_(false), determined_type_(false)
{ {
gcc_assert(type != NULL || init != NULL); gcc_assert(type != NULL || init != NULL);
gcc_assert(!is_parameter || init == NULL); gcc_assert(!is_parameter || init == NULL);
...@@ -3456,6 +3456,10 @@ Variable::type() const ...@@ -3456,6 +3456,10 @@ Variable::type() const
void void
Variable::determine_type() Variable::determine_type()
{ {
if (this->determined_type_)
return;
this->determined_type_ = true;
if (this->preinit_ != NULL) if (this->preinit_ != NULL)
this->preinit_->determine_types(); this->preinit_->determine_types();
......
...@@ -1307,6 +1307,8 @@ class Variable ...@@ -1307,6 +1307,8 @@ class Variable
bool type_from_chan_element_ : 1; bool type_from_chan_element_ : 1;
// True if this is a variable created for a type switch case. // True if this is a variable created for a type switch case.
bool is_type_switch_var_ : 1; bool is_type_switch_var_ : 1;
// True if we have determined types.
bool determined_type_ : 1;
}; };
// A variable which is really the name for a function return value, or // A variable which is really the name for a function return value, or
......
...@@ -970,7 +970,7 @@ Tuple_map_assignment_statement::do_lower(Gogo*, Block* enclosing) ...@@ -970,7 +970,7 @@ Tuple_map_assignment_statement::do_lower(Gogo*, Block* enclosing)
param_types->push_back(Typed_identifier("val", pval_type, bloc)); param_types->push_back(Typed_identifier("val", pval_type, bloc));
Typed_identifier_list* ret_types = new Typed_identifier_list(); Typed_identifier_list* ret_types = new Typed_identifier_list();
ret_types->push_back(Typed_identifier("", Type::make_boolean_type(), bloc)); ret_types->push_back(Typed_identifier("", Type::lookup_bool_type(), bloc));
Function_type* fntype = Type::make_function_type(NULL, param_types, Function_type* fntype = Type::make_function_type(NULL, param_types,
ret_types, bloc); ret_types, bloc);
...@@ -2026,7 +2026,7 @@ Thunk_statement::build_struct(Function_type* fntype) ...@@ -2026,7 +2026,7 @@ Thunk_statement::build_struct(Function_type* fntype)
// we add an argument when building recover thunks. Handle that // we add an argument when building recover thunks. Handle that
// here. // here.
fields->push_back(Struct_field(Typed_identifier("can_recover", fields->push_back(Struct_field(Typed_identifier("can_recover",
Type::make_boolean_type(), Type::lookup_bool_type(),
location))); location)));
} }
...@@ -2103,7 +2103,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name, ...@@ -2103,7 +2103,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
// return value, to disable tail call optimizations which will // return value, to disable tail call optimizations which will
// break the way we check whether recover is permitted. // break the way we check whether recover is permitted.
thunk_results = new Typed_identifier_list(); thunk_results = new Typed_identifier_list();
thunk_results->push_back(Typed_identifier("", Type::make_boolean_type(), thunk_results->push_back(Typed_identifier("", Type::lookup_bool_type(),
location)); location));
} }
...@@ -2135,7 +2135,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name, ...@@ -2135,7 +2135,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
Typed_identifier_list* result_types = new Typed_identifier_list(); Typed_identifier_list* result_types = new Typed_identifier_list();
result_types->push_back(Typed_identifier("", result_types->push_back(Typed_identifier("",
Type::make_boolean_type(), Type::lookup_bool_type(),
bloc)); bloc));
Function_type* t = Type::make_function_type(NULL, param_types, Function_type* t = Type::make_function_type(NULL, param_types,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment