diff mbox

Go patch committed: Fix array dimension handling on 32-bit host

Message ID CAOyqgcVvcKMMrgjSMH8gL-Ny5QEym=6pNQM7cHNq4MHKT_4W9w@mail.gmail.com
State New
Headers show

Commit Message

Ian Lance Taylor Dec. 2, 2015, 1:28 a.m. UTC
The Go frontend code that handled array dimensions when generating
reflection and mangling assumed that an array dimension would fit in
an unsigned long.  That is of course not true when a 32-bit host is
cross-compiling to a 64-bit target.  This patch fixes the problem.
This was reported as GCC PR 65717.  Bootstrapped and ran Go tests on
x86_64-pc-linux-gnu, and also on a 32-bit Solaris host crossing to a
64-bit Solaris target.  Committed to mainline.  Could be committed to
GCC 5 branch but I'm not sure whether the branch is open yet.

Ian

Comments

Richard Biener Dec. 2, 2015, 9:58 a.m. UTC | #1
On Wed, Dec 2, 2015 at 2:28 AM, Ian Lance Taylor <iant@golang.org> wrote:
> The Go frontend code that handled array dimensions when generating
> reflection and mangling assumed that an array dimension would fit in
> an unsigned long.  That is of course not true when a 32-bit host is
> cross-compiling to a 64-bit target.  This patch fixes the problem.
> This was reported as GCC PR 65717.  Bootstrapped and ran Go tests on
> x86_64-pc-linux-gnu, and also on a 32-bit Solaris host crossing to a
> 64-bit Solaris target.  Committed to mainline.  Could be committed to
> GCC 5 branch but I'm not sure whether the branch is open yet.

It is not, it will be again after GCC 5.3.0 was released next week.

Richard.

> Ian
diff mbox

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 231095)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-81eb6a3f425b2158c67ee32c0cc973a72ce9d6be
+c375f3bf470f94220149b486c947bb3eb57cde7d
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 231095)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -6398,22 +6398,21 @@  Array_type::do_reflection(Gogo* gogo, st
   if (this->length_ != NULL)
     {
       Numeric_constant nc;
-      unsigned long val;
-      if (!this->length_->numeric_constant_value(&nc)
-	  || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
+      if (!this->length_->numeric_constant_value(&nc))
 	{
-	  if (!this->issued_length_error_)
-	    {
-	      error_at(this->length_->location(), "invalid array length");
-	      this->issued_length_error_ = true;
-	    }
+	  go_assert(saw_errors());
+	  return;
 	}
-      else
+      mpz_t val;
+      if (!nc.to_int(&val))
 	{
-	  char buf[50];
-	  snprintf(buf, sizeof buf, "%lu", val);
-	  ret->append(buf);
+	  go_assert(saw_errors());
+	  return;
 	}
+      char* s = mpz_get_str(NULL, 10, val);
+      ret->append(s);
+      free(s);
+      mpz_clear(val);
     }
   ret->push_back(']');
 
@@ -6544,22 +6543,21 @@  Array_type::do_mangled_name(Gogo* gogo,
   if (this->length_ != NULL)
     {
       Numeric_constant nc;
-      unsigned long val;
-      if (!this->length_->numeric_constant_value(&nc)
-	  || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
+      if (!this->length_->numeric_constant_value(&nc))
 	{
-	  if (!this->issued_length_error_)
-	    {
-	      error_at(this->length_->location(), "invalid array length");
-	      this->issued_length_error_ = true;
-	    }
+	  go_assert(saw_errors());
+	  return;
 	}
-      else
+      mpz_t val;
+      if (!nc.to_int(&val))
 	{
-	  char buf[50];
-	  snprintf(buf, sizeof buf, "%lu", val);
-	  ret->append(buf);
+	  go_assert(saw_errors());
+	  return;
 	}
+      char *s = mpz_get_str(NULL, 10, val);
+      ret->append(s);
+      free(s);
+      mpz_clear(val);
     }
   ret->push_back('e');
 }