Patchwork Go patch committed: Fix some type determination issues

login
register
mail settings
Submitter Ian Taylor
Date June 25, 2013, 4:38 p.m.
Message ID <mcrr4fqkuwc.fsf@iant-glaptop.roam.corp.google.com>
Download mbox | patch
Permalink /patch/254242/
State New
Headers show

Comments

Ian Taylor - June 25, 2013, 4:38 p.m.
This patch to the Go frontend fixes some type determination issues that
show up in the current master Go testsuite.  There were some cases where
types were not being determined, which lead to incorrect error messages
and in some cases the wrong thing happening.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline and 4.8
branch.

Ian

Patch

diff -r 478ec87a337f go/expressions.cc
--- a/go/expressions.cc	Mon Jun 24 16:09:40 2013 -0700
+++ b/go/expressions.cc	Tue Jun 25 09:21:43 2013 -0700
@@ -5668,6 +5668,7 @@ 
       if (tleft->is_abstract()
 	  && subcontext.type != NULL
 	  && !subcontext.may_be_abstract
+	  && subcontext.type->interface_type() == NULL
 	  && subcontext.type->integer_type() == NULL)
 	this->report_error(("invalid context-determined non-integer type "
 			    "for left operand of shift"));
@@ -7383,6 +7384,8 @@ 
   Type* uintptr_type = Type::lookup_integer_type("uintptr");
   int uintptr_bits = uintptr_type->integer_type()->bits();
 
+  Type_context int_context(Type::lookup_integer_type("int"), false);
+
   ++parg;
   Expression* len_arg;
   if (parg == args->end())
@@ -7401,6 +7404,7 @@ 
   else
     {
       len_arg = *parg;
+      len_arg->determine_type(&int_context);
       if (!this->check_int_value(len_arg, true))
 	return Expression::make_error(this->location());
       if (len_arg->type()->integer_type() != NULL
@@ -7413,6 +7417,7 @@ 
   if (is_slice && parg != args->end())
     {
       cap_arg = *parg;
+      cap_arg->determine_type(&int_context);
       if (!this->check_int_value(cap_arg, false))
 	return Expression::make_error(this->location());
 
@@ -8030,6 +8035,8 @@ 
     case BUILTIN_REAL:
     case BUILTIN_IMAG:
       arg_type = Builtin_call_expression::complex_type(context->type);
+      if (arg_type == NULL)
+	arg_type = Type::lookup_complex_type("complex128");
       is_print = false;
       break;
 
@@ -8038,6 +8045,8 @@ 
 	// For the complex function the type of one operand can
 	// determine the type of the other, as in a binary expression.
 	arg_type = Builtin_call_expression::real_imag_type(context->type);
+	if (arg_type == NULL)
+	  arg_type = Type::lookup_float_type("float64");
 	if (args != NULL && args->size() == 2)
 	  {
 	    Type* t1 = args->front()->type();
@@ -10379,13 +10388,20 @@ 
 void
 Array_index_expression::do_check_types(Gogo*)
 {
-  if (this->start_->type()->integer_type() == NULL)
+  Numeric_constant nc;
+  unsigned long v;
+  if (this->start_->type()->integer_type() == NULL
+      && !this->start_->type()->is_error()
+      && (!this->start_->numeric_constant_value(&nc)
+	  || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
     this->report_error(_("index must be integer"));
   if (this->end_ != NULL
       && this->end_->type()->integer_type() == NULL
       && !this->end_->type()->is_error()
       && !this->end_->is_nil_expression()
-      && !this->end_->is_error_expression())
+      && !this->end_->is_error_expression()
+      && (!this->end_->numeric_constant_value(&nc)
+	  || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
     this->report_error(_("slice end must be integer"));
 
   Array_type* array_type = this->array_->type()->array_type();
diff -r 478ec87a337f go/statements.cc
--- a/go/statements.cc	Mon Jun 24 16:09:40 2013 -0700
+++ b/go/statements.cc	Tue Jun 25 09:21:43 2013 -0700
@@ -569,7 +569,10 @@ 
 Assignment_statement::do_determine_types()
 {
   this->lhs_->determine_type_no_context();
-  Type_context context(this->lhs_->type(), false);
+  Type* rhs_context_type = this->lhs_->type();
+  if (rhs_context_type->is_sink_type())
+    rhs_context_type = NULL;
+  Type_context context(rhs_context_type, false);
   this->rhs_->determine_type(&context);
 }