Add check array out of bound.
--- 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);