stage3/array_range_check.cc
changeset 581 1e158dc9f9c1
parent 560 13b5b7faa3d7
child 583 e1df3781be84
equal deleted inserted replaced
580:b6350d9f204d 581:1e158dc9f9c1
    67     fprintf(stderr, __VA_ARGS__);                                                                                           \
    67     fprintf(stderr, __VA_ARGS__);                                                                                           \
    68     fprintf(stderr, "\n");                                                                                                  \
    68     fprintf(stderr, "\n");                                                                                                  \
    69     warning_found = true;                                                                                                   \
    69     warning_found = true;                                                                                                   \
    70 }
    70 }
    71 
    71 
       
    72 #define GET_CVALUE(dtype, symbol)             ((symbol)->const_value_##dtype->value)
       
    73 #define VALID_CVALUE(dtype, symbol)           ((NULL != (symbol)->const_value_##dtype) && (symbol_c::cs_const_value == (symbol)->const_value_##dtype->status))
       
    74 
       
    75 
    72 
    76 
    73 array_range_check_c::array_range_check_c(symbol_c *ignore) {
    77 array_range_check_c::array_range_check_c(symbol_c *ignore) {
    74 	error_count = 0;
    78 	error_count = 0;
    75 	current_display_error_level = 0;
    79 	current_display_error_level = 0;
    76 }
    80 }
    91 	for (dimension_count = 0; NULL != array_dimension_iterator.next(); dimension_count++);
    95 	for (dimension_count = 0; NULL != array_dimension_iterator.next(); dimension_count++);
    92 	if (dimension_count != ((list_c *)symbol->subscript_list)->n)
    96 	if (dimension_count != ((list_c *)symbol->subscript_list)->n)
    93 		STAGE3_ERROR(0, symbol, symbol, "Number of dimensions does not match, Array have %d dimension(s)", dimension_count);
    97 		STAGE3_ERROR(0, symbol, symbol, "Number of dimensions does not match, Array have %d dimension(s)", dimension_count);
    94 }
    98 }
    95 
    99 
       
   100 void array_range_check_c::check_bounds(array_variable_c *symbol) {
       
   101   list_c *l;
       
   102   symbol_c *var_decl;
       
   103 
       
   104   l = (list_c *)symbol->subscript_list;
       
   105   var_decl = search_varfb_instance_type->get_basetype_decl(symbol->subscripted_variable);
       
   106   array_dimension_iterator_c array_dimension_iterator(var_decl);
       
   107   for (int i =  0; i < l->n; i++) {
       
   108     subrange_c *dimension = array_dimension_iterator.next();
       
   109     /* Index is not constant*/
       
   110     if (!VALID_CVALUE(int64, l->elements[i]))
       
   111     	continue;
       
   112     /* Limits must be constant */
       
   113     if (!VALID_CVALUE(int64,  dimension->lower_limit) ||!VALID_CVALUE(int64,  dimension->upper_limit))
       
   114         ERROR;
       
   115 
       
   116     if ( GET_CVALUE(int64, l->elements[i]) < GET_CVALUE(int64, dimension->lower_limit) ||
       
   117     	 GET_CVALUE(int64, l->elements[i]) > GET_CVALUE(int64, dimension->upper_limit))
       
   118       STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds.");
       
   119   }
       
   120 }
       
   121 
    96 /*********************/
   122 /*********************/
    97 /* B 1.4 - Variables */
   123 /* B 1.4 - Variables */
    98 /*********************/
   124 /*********************/
    99 /*************************************/
   125 /*************************************/
   100 /* B 1.4.2 - Multi-element variables */
   126 /* B 1.4.2 - Multi-element variables */
   101 /*************************************/
   127 /*************************************/
   102 void *array_range_check_c::visit(array_variable_c *symbol) {
   128 void *array_range_check_c::visit(array_variable_c *symbol) {
   103 	check_dimension_count(symbol);
   129 	check_dimension_count(symbol);
       
   130 	check_bounds(symbol);
   104 	return NULL;
   131 	return NULL;
   105 }
   132 }
   106 
   133 
   107 
   134 
   108 /**************************************/
   135 /**************************************/