Patchwork Go patch committed: Error for inverted slice range

login
register
mail settings
Submitter Ian Taylor
Date Dec. 4, 2012, 9:10 a.m.
Message ID <mcrip8irxnb.fsf@google.com>
Download mbox | patch
Permalink /patch/203584/
State New
Headers show

Comments

Ian Taylor - Dec. 4, 2012, 9:10 a.m.
An inverted slice range (with the low index larger than the high index)
is invalid in Go.  An inverted slice range using constant indexes is
supposed to be detected at compile time.  This patch implements that in
gccgo.  Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

Patch

diff -r f9cf17ff5228 go/expressions.cc
--- a/go/expressions.cc	Mon Dec 03 22:43:30 2012 -0800
+++ b/go/expressions.cc	Tue Dec 04 01:03:48 2012 -0800
@@ -9770,8 +9770,10 @@ 
 		     && lvalnc.to_int(&lval));
   Numeric_constant inc;
   mpz_t ival;
+  bool ival_valid = false;
   if (this->start_->numeric_constant_value(&inc) && inc.to_int(&ival))
     {
+      ival_valid = true;
       if (mpz_sgn(ival) < 0
 	  || mpz_sizeinbase(ival, 2) >= int_bits
 	  || (lval_valid
@@ -9782,7 +9784,6 @@ 
 	  error_at(this->start_->location(), "array index out of bounds");
 	  this->set_is_error();
 	}
-      mpz_clear(ival);
     }
   if (this->end_ != NULL && !this->end_->is_nil_expression())
     {
@@ -9797,9 +9798,13 @@ 
 	      error_at(this->end_->location(), "array index out of bounds");
 	      this->set_is_error();
 	    }
+	  else if (ival_valid && mpz_cmp(ival, eval) > 0)
+	    this->report_error(_("inverted slice range"));
 	  mpz_clear(eval);
 	}
     }
+  if (ival_valid)
+    mpz_clear(ival);
   if (lval_valid)
     mpz_clear(lval);
 
@@ -10180,15 +10185,16 @@ 
 
   Numeric_constant inc;
   mpz_t ival;
+  bool ival_valid = false;
   if (this->start_->numeric_constant_value(&inc) && inc.to_int(&ival))
     {
+      ival_valid = true;
       if (mpz_sgn(ival) < 0
 	  || (sval_valid && mpz_cmp_ui(ival, sval.length()) >= 0))
 	{
 	  error_at(this->start_->location(), "string index out of bounds");
 	  this->set_is_error();
 	}
-      mpz_clear(ival);
     }
   if (this->end_ != NULL && !this->end_->is_nil_expression())
     {
@@ -10202,9 +10208,13 @@ 
 	      error_at(this->end_->location(), "string index out of bounds");
 	      this->set_is_error();
 	    }
+	  else if (ival_valid && mpz_cmp(ival, eval) > 0)
+	    this->report_error(_("inverted slice range"));
 	  mpz_clear(eval);
 	}
     }
+  if (ival_valid)
+    mpz_clear(ival);
 }
 
 // Get a tree for a string index.