Add check array out of bound.
authorManuele Conti <conti.ma@alice.it>
Mon, 11 Jun 2012 22:38:36 +0200
changeset 581 1e158dc9f9c1
parent 580 b6350d9f204d
child 582 8495119e7271
Add check array out of bound.
stage3/array_range_check.cc
stage3/array_range_check.hh
--- a/stage3/array_range_check.cc	Mon Jun 11 18:48:58 2012 +0100
+++ b/stage3/array_range_check.cc	Mon Jun 11 22:38:36 2012 +0200
@@ -69,6 +69,10 @@
     warning_found = true;                                                                                                   \
 }
 
+#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value_##dtype->value)
+#define VALID_CVALUE(dtype, symbol)           ((NULL != (symbol)->const_value_##dtype) && (symbol_c::cs_const_value == (symbol)->const_value_##dtype->status))
+
+
 
 array_range_check_c::array_range_check_c(symbol_c *ignore) {
 	error_count = 0;
@@ -93,6 +97,28 @@
 		STAGE3_ERROR(0, symbol, symbol, "Number of dimensions does not match, Array have %d dimension(s)", dimension_count);
 }
 
+void array_range_check_c::check_bounds(array_variable_c *symbol) {
+  list_c *l;
+  symbol_c *var_decl;
+
+  l = (list_c *)symbol->subscript_list;
+  var_decl = search_varfb_instance_type->get_basetype_decl(symbol->subscripted_variable);
+  array_dimension_iterator_c array_dimension_iterator(var_decl);
+  for (int i =  0; i < l->n; i++) {
+    subrange_c *dimension = array_dimension_iterator.next();
+    /* Index is not constant*/
+    if (!VALID_CVALUE(int64, l->elements[i]))
+    	continue;
+    /* Limits must be constant */
+    if (!VALID_CVALUE(int64,  dimension->lower_limit) ||!VALID_CVALUE(int64,  dimension->upper_limit))
+        ERROR;
+
+    if ( GET_CVALUE(int64, l->elements[i]) < GET_CVALUE(int64, dimension->lower_limit) ||
+    	 GET_CVALUE(int64, l->elements[i]) > GET_CVALUE(int64, dimension->upper_limit))
+      STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds.");
+  }
+}
+
 /*********************/
 /* B 1.4 - Variables */
 /*********************/
@@ -101,6 +127,7 @@
 /*************************************/
 void *array_range_check_c::visit(array_variable_c *symbol) {
 	check_dimension_count(symbol);
+	check_bounds(symbol);
 	return NULL;
 }
 
--- a/stage3/array_range_check.hh	Mon Jun 11 18:48:58 2012 +0100
+++ b/stage3/array_range_check.hh	Mon Jun 11 22:38:36 2012 +0200
@@ -37,7 +37,6 @@
 
 
 
-
 class array_range_check_c: public iterator_visitor_c {
 
   private:
@@ -48,6 +47,7 @@
     int current_display_error_level;
 
     void check_dimension_count(array_variable_c *symbol);
+    void check_bounds(array_variable_c *symbol);
 
   public:
     array_range_check_c(symbol_c *ignore);