94 array_dimension_iterator_c array_dimension_iterator(var_decl); |
102 array_dimension_iterator_c array_dimension_iterator(var_decl); |
95 for (dimension_count = 0; NULL != array_dimension_iterator.next(); dimension_count++); |
103 for (dimension_count = 0; NULL != array_dimension_iterator.next(); dimension_count++); |
96 if (dimension_count != ((list_c *)symbol->subscript_list)->n) |
104 if (dimension_count != ((list_c *)symbol->subscript_list)->n) |
97 STAGE3_ERROR(0, symbol, symbol, "Number of subscripts/indexes does not match the number of subscripts/indexes in the array's declaration (array has %d indexes)", dimension_count); |
105 STAGE3_ERROR(0, symbol, symbol, "Number of subscripts/indexes does not match the number of subscripts/indexes in the array's declaration (array has %d indexes)", dimension_count); |
98 } |
106 } |
|
107 |
|
108 |
99 |
109 |
100 void array_range_check_c::check_bounds(array_variable_c *symbol) { |
110 void array_range_check_c::check_bounds(array_variable_c *symbol) { |
101 list_c *l; /* the subscript_list */ |
111 list_c *l; /* the subscript_list */ |
102 symbol_c *var_decl; |
112 symbol_c *var_decl; |
103 |
113 |
126 if ( GET_CVALUE(uint64, l->elements[i]) > GET_CVALUE(uint64, dimension->upper_limit)) |
136 if ( GET_CVALUE(uint64, l->elements[i]) > GET_CVALUE(uint64, dimension->upper_limit)) |
127 {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds."); continue;} |
137 {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds."); continue;} |
128 } |
138 } |
129 } |
139 } |
130 |
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 /*************************/ |
|
150 /* B.1 - Common elements */ |
|
151 /*************************/ |
|
152 /**********************/ |
|
153 /* B.1.3 - Data types */ |
|
154 /**********************/ |
|
155 /********************************/ |
|
156 /* B 1.3.3 - Derived data types */ |
|
157 /********************************/ |
|
158 |
|
159 /* signed_integer DOTDOT signed_integer */ |
|
160 /* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */ |
|
161 // SYM_REF2(subrange_c, lower_limit, upper_limit, unsigned long long int dimension) |
|
162 void *array_range_check_c::visit(subrange_c *symbol) { |
|
163 unsigned long long int dimension = 0; // we use unsigned long long instead of uint64_t since it might just happen to be larger than uint64_t in the platform used for compiling this code!! |
|
164 |
|
165 /* Determine the size of the array... */ |
|
166 if (VALID_CVALUE( int64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) { |
|
167 // do the sums in such a way that no overflow is possible... even during intermediate steps used by compiler! |
|
168 // remember that the result (dimension) is unsigned, while the operands are signed!! |
|
169 // dimension = GET_CVALUE( int64, symbol->upper_limit) - VALID_CVALUE( int64, symbol->lower_limit); |
|
170 if (VALID_CVALUE( int64, symbol->lower_limit) >= 0) { |
|
171 dimension = GET_CVALUE( int64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit); |
|
172 } else { |
|
173 dimension = -GET_CVALUE( int64, symbol->lower_limit); |
|
174 dimension += GET_CVALUE( int64, symbol->upper_limit); |
|
175 } |
|
176 } else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE(uint64, symbol->lower_limit)) { |
|
177 dimension = GET_CVALUE(uint64, symbol->upper_limit) - VALID_CVALUE(uint64, symbol->lower_limit); |
|
178 } else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) { |
|
179 if (VALID_CVALUE( int64, symbol->lower_limit) >= 0) { |
|
180 dimension = GET_CVALUE( int64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit); |
|
181 } else { |
|
182 unsigned long long int lower_ull; |
|
183 lower_ull = -GET_CVALUE( int64, symbol->lower_limit); |
|
184 dimension = GET_CVALUE( int64, symbol->upper_limit) + lower_ull; |
|
185 /* TODO: check this overflow test, it does not seem to be working. I don't have to go now... Will check later. */ |
|
186 if (dimension < lower_ull) |
|
187 STAGE3_ERROR(0, symbol, symbol, "Number of elements in array subrange exceeds maximum number of elements (%llu).", std::numeric_limits< unsigned long long int >::max()); |
|
188 } |
|
189 } else ERROR; |
|
190 |
|
191 /* correct value for dimension is actually ---> dimension = upper_limit - lower_limit + 1 |
|
192 * Up to now, we have only determined dimension = upper_limit - lower_limit |
|
193 * We must first check whether this last increment will cause an overflow! |
|
194 */ |
|
195 if (dimension == std::numeric_limits< unsigned long long int >::max()) |
|
196 STAGE3_ERROR(0, symbol, symbol, "Number of elements in array subrange exceeds maximum number of elements (%llu).", std::numeric_limits< unsigned long long int >::max()); |
|
197 |
|
198 /* correct value for dimension is actually ---> dimension = upper_limit - lower_limit + 1 */ |
|
199 dimension++; |
|
200 |
|
201 symbol->dimension = dimension; |
|
202 return NULL; |
|
203 } |
|
204 |
|
205 |
131 /*********************/ |
206 /*********************/ |
132 /* B 1.4 - Variables */ |
207 /* B 1.4 - Variables */ |
133 /*********************/ |
208 /*********************/ |
134 /*************************************/ |
209 /*************************************/ |
135 /* B 1.4.2 - Multi-element variables */ |
210 /* B 1.4.2 - Multi-element variables */ |
145 /* B 1.5 - Program organisation units */ |
220 /* B 1.5 - Program organisation units */ |
146 /**************************************/ |
221 /**************************************/ |
147 /***********************/ |
222 /***********************/ |
148 /* B 1.5.1 - Functions */ |
223 /* B 1.5.1 - Functions */ |
149 /***********************/ |
224 /***********************/ |
|
225 // SYM_REF4(function_declaration_c, derived_function_name, type_name, var_declarations_list, function_body) |
150 void *array_range_check_c::visit(function_declaration_c *symbol) { |
226 void *array_range_check_c::visit(function_declaration_c *symbol) { |
|
227 symbol->var_declarations_list->accept(*this); // required for visiting subrange_c |
151 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
228 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
152 // search_var_instance_decl = new search_var_instance_decl_c(symbol); |
229 // search_var_instance_decl = new search_var_instance_decl_c(symbol); |
153 symbol->function_body->accept(*this); |
230 symbol->function_body->accept(*this); |
154 delete search_varfb_instance_type; |
231 delete search_varfb_instance_type; |
155 // delete search_var_instance_decl; |
232 // delete search_var_instance_decl; |
159 } |
236 } |
160 |
237 |
161 /*****************************/ |
238 /*****************************/ |
162 /* B 1.5.2 - Function blocks */ |
239 /* B 1.5.2 - Function blocks */ |
163 /*****************************/ |
240 /*****************************/ |
|
241 // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body) |
164 void *array_range_check_c::visit(function_block_declaration_c *symbol) { |
242 void *array_range_check_c::visit(function_block_declaration_c *symbol) { |
|
243 symbol->var_declarations->accept(*this); // required for visiting subrange_c |
165 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
244 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
166 // search_var_instance_decl = new search_var_instance_decl_c(symbol); |
245 // search_var_instance_decl = new search_var_instance_decl_c(symbol); |
167 symbol->fblock_body->accept(*this); |
246 symbol->fblock_body->accept(*this); |
168 delete search_varfb_instance_type; |
247 delete search_varfb_instance_type; |
169 // delete search_var_instance_decl; |
248 // delete search_var_instance_decl; |
173 } |
252 } |
174 |
253 |
175 /**********************/ |
254 /**********************/ |
176 /* B 1.5.3 - Programs */ |
255 /* B 1.5.3 - Programs */ |
177 /**********************/ |
256 /**********************/ |
|
257 // SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body) |
178 void *array_range_check_c::visit(program_declaration_c *symbol) { |
258 void *array_range_check_c::visit(program_declaration_c *symbol) { |
|
259 symbol->var_declarations->accept(*this); // required for visiting subrange_c |
179 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
260 search_varfb_instance_type = new search_varfb_instance_type_c(symbol); |
180 // search_var_instance_decl = new search_var_instance_decl_c(symbol); |
261 // search_var_instance_decl = new search_var_instance_decl_c(symbol); |
181 symbol->function_block_body->accept(*this); |
262 symbol->function_block_body->accept(*this); |
182 delete search_varfb_instance_type; |
263 delete search_varfb_instance_type; |
183 // delete search_var_instance_decl; |
264 // delete search_var_instance_decl; |