Patchwork Go patch committed: Make sure variable type is determined

login
register
mail settings
Submitter Ian Taylor
Date March 3, 2011, 4:28 a.m.
Message ID <mcrk4gg3k0k.fsf@google.com>
Download mbox | patch
Permalink /patch/85228/
State New
Headers show

Comments

Ian Taylor - March 3, 2011, 4:28 a.m.
This patch to the Go frontend makes sure that the type of a variable is
determined even when the variable is initialized from the value of a
variable which has not yet been declared.  Making this work required
fixing several uses of the untyped boolean type to correctly use the
named boolean type instead.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

Patch

diff -r 61c84c273f21 go/expressions.cc
--- a/go/expressions.cc	Wed Mar 02 19:30:37 2011 -0800
+++ b/go/expressions.cc	Wed Mar 02 20:13:57 2011 -0800
@@ -957,6 +957,15 @@ 
     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
 // may want to move the variable onto the heap.
 
diff -r 61c84c273f21 go/expressions.h
--- a/go/expressions.h	Wed Mar 02 19:30:37 2011 -0800
+++ b/go/expressions.h	Wed Mar 02 20:13:57 2011 -0800
@@ -915,8 +915,7 @@ 
   do_type();
 
   void
-  do_determine_type(const Type_context*)
-  { }
+  do_determine_type(const Type_context*);
 
   Expression*
   do_copy()
diff -r 61c84c273f21 go/gogo.cc
--- a/go/gogo.cc	Wed Mar 02 19:30:37 2011 -0800
+++ b/go/gogo.cc	Wed Mar 02 20:13:57 2011 -0800
@@ -1730,7 +1730,7 @@ 
   Block* retblock = new Block(enclosing, 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);
   retblock->add_statement(ts);
 
@@ -2086,7 +2086,7 @@ 
   ++count;
   std::string can_recover_name = buf;
   new_params->push_back(Typed_identifier(can_recover_name,
-					 Type::make_boolean_type(),
+					 Type::lookup_bool_type(),
 					 orig_fntype->location()));
 
   const Typed_identifier_list* orig_results = orig_fntype->results();
@@ -2222,7 +2222,7 @@ 
 
   // Add the can_recover argument to the (now) new bindings, and
   // 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);
   can_recover_no = new_bindings->add_variable(can_recover_name, NULL,
 					      can_recover_var);
@@ -2273,7 +2273,7 @@ 
       Typed_identifier_list* param_types = new Typed_identifier_list();
       Type* voidptr_type = Type::make_pointer_type(Type::make_void_type());
       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();
       results->push_back(Typed_identifier("", boolean_type, bloc));
       Function_type* fntype = Type::make_function_type(NULL, param_types,
@@ -3216,7 +3216,7 @@ 
     is_address_taken_(false), seen_(false), init_is_lowered_(false),
     type_from_init_tuple_(false), type_from_range_index_(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(!is_parameter || init == NULL);
@@ -3456,6 +3456,10 @@ 
 void
 Variable::determine_type()
 {
+  if (this->determined_type_)
+    return;
+  this->determined_type_ = true;
+
   if (this->preinit_ != NULL)
     this->preinit_->determine_types();
 
diff -r 61c84c273f21 go/gogo.h
--- a/go/gogo.h	Wed Mar 02 19:30:37 2011 -0800
+++ b/go/gogo.h	Wed Mar 02 20:13:57 2011 -0800
@@ -1307,6 +1307,8 @@ 
   bool type_from_chan_element_ : 1;
   // True if this is a variable created for a type switch case.
   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
diff -r 61c84c273f21 go/statements.cc
--- a/go/statements.cc	Wed Mar 02 19:30:37 2011 -0800
+++ b/go/statements.cc	Wed Mar 02 20:13:57 2011 -0800
@@ -970,7 +970,7 @@ 
   param_types->push_back(Typed_identifier("val", pval_type, bloc));
 
   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,
 						   ret_types, bloc);
@@ -2026,7 +2026,7 @@ 
       // we add an argument when building recover thunks.  Handle that
       // here.
       fields->push_back(Struct_field(Typed_identifier("can_recover",
-						      Type::make_boolean_type(),
+						      Type::lookup_bool_type(),
 						      location)));
     }
 
@@ -2103,7 +2103,7 @@ 
       // return value, to disable tail call optimizations which will
       // break the way we check whether recover is permitted.
       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));
     }
 
@@ -2135,7 +2135,7 @@ 
 
 	  Typed_identifier_list* result_types = new Typed_identifier_list();
 	  result_types->push_back(Typed_identifier("",
-						   Type::make_boolean_type(),
+						   Type::lookup_bool_type(),
 						   bloc));
 
 	  Function_type* t = Type::make_function_type(NULL, param_types,