stage3/array_range_check.cc
changeset 598 0b1ee7e7123b
parent 594 c8092e909886
child 599 60f3edcf6a8f
equal deleted inserted replaced
597:7326a0658104 598:0b1ee7e7123b
   162 /* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */
   162 /* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */
   163 // SYM_REF2(subrange_c, lower_limit, upper_limit, unsigned long long int dimension)
   163 // SYM_REF2(subrange_c, lower_limit, upper_limit, unsigned long long int dimension)
   164 void *array_range_check_c::visit(subrange_c *symbol) {
   164 void *array_range_check_c::visit(subrange_c *symbol) {
   165 	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!!
   165 	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!!
   166 
   166 
   167 /* Determine the size of the array... */
   167 	/* Determine the size of the array... */
   168 	if        (VALID_CVALUE( int64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) {  
   168 	if        (VALID_CVALUE( int64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) {  
   169 		// do the sums in such a way that no overflow is possible... even during intermediate steps used by compiler!
   169 		// do the sums in such a way that no overflow is possible... even during intermediate steps used by compiler!
   170 		// remember that the result (dimension) is unsigned, while the operands are signed!!
   170 		// remember that the result (dimension) is unsigned, while the operands are signed!!
   171 		// dimension = GET_CVALUE( int64, symbol->upper_limit) - VALID_CVALUE( int64, symbol->lower_limit);
   171 		// dimension = GET_CVALUE( int64, symbol->upper_limit) - VALID_CVALUE( int64, symbol->lower_limit);
   172 		if (VALID_CVALUE( int64, symbol->lower_limit) >= 0) {
   172 		if (GET_CVALUE( int64, symbol->lower_limit) >= 0) {
   173 			dimension = GET_CVALUE( int64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit);
   173 			dimension = GET_CVALUE( int64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit);
   174 		} else {
   174 		} else {
   175 			dimension  = -GET_CVALUE( int64, symbol->lower_limit);
   175 			dimension  = -GET_CVALUE( int64, symbol->lower_limit);
   176 			dimension +=  GET_CVALUE( int64, symbol->upper_limit);     
   176 			dimension +=  GET_CVALUE( int64, symbol->upper_limit);     
   177 		}
   177 		}
   178 	} else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE(uint64, symbol->lower_limit)) {
   178 	} else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE(uint64, symbol->lower_limit)) {
   179 		dimension = GET_CVALUE(uint64, symbol->upper_limit) - VALID_CVALUE(uint64, symbol->lower_limit); 
   179 		dimension = GET_CVALUE(uint64, symbol->upper_limit) - GET_CVALUE(uint64, symbol->lower_limit); 
   180 	} else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) {
   180 	} else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) {
   181 		if (VALID_CVALUE( int64, symbol->lower_limit) >= 0) {
   181 		if (GET_CVALUE( int64, symbol->lower_limit) >= 0) {
   182 			dimension = GET_CVALUE( int64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit);
   182 			dimension = GET_CVALUE(uint64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit);
   183 		} else {
   183 		} else {
   184 		unsigned long long int lower_ull;
   184 			unsigned long long int lower_ull;
   185 		lower_ull  = -GET_CVALUE( int64, symbol->lower_limit);
   185 			lower_ull  = -GET_CVALUE( int64, symbol->lower_limit);
   186 		dimension  =  GET_CVALUE( int64, symbol->upper_limit) + lower_ull;     
   186 			dimension  =  GET_CVALUE(uint64, symbol->upper_limit) + lower_ull;     
   187 		/* TODO: check this overflow test, it does not seem to be working. I don't have to go now... Will check later. */
   187 			if (dimension < lower_ull)
   188 		if (dimension < lower_ull)
   188 				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());
   189 			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());
       
   190 		}
   189 		}
   191 	} else ERROR;
   190 	} else ERROR;
   192 
   191 
   193 	/* correct value for dimension is actually ---> dimension = upper_limit - lower_limit + 1
   192 	/* correct value for dimension is actually ---> dimension = upper_limit - lower_limit + 1
   194 	 * Up to now, we have only determined dimension = upper_limit - lower_limit
   193 	 * Up to now, we have only determined dimension = upper_limit - lower_limit
   201 	dimension++; 
   200 	dimension++; 
   202 	
   201 	
   203 	symbol->dimension = dimension;
   202 	symbol->dimension = dimension;
   204 	return NULL;
   203 	return NULL;
   205 }
   204 }
       
   205 
       
   206 
       
   207 
       
   208 
       
   209 
       
   210 /* integer '(' [array_initial_element] ')' */
       
   211 /* array_initial_element may be NULL ! */
       
   212 // SYM_REF2(array_initial_elements_c, integer, array_initial_element)
       
   213 void *array_range_check_c::visit(array_initial_elements_c *symbol) {
       
   214 	if (VALID_CVALUE( int64, symbol->integer) && (GET_CVALUE( int64, symbol->integer) < 0)) 
       
   215 		ERROR; /* the IEC 61131-3 syntax guarantees that this value will never be negative! */
       
   216 
       
   217 	/* TODO: check that the total number of 'initial values' does not exceed the size of the array! */
       
   218 
       
   219 	return NULL;
       
   220 }
       
   221 
       
   222 
       
   223 
       
   224 
       
   225 
       
   226 
       
   227 
   206 
   228 
   207 
   229 
   208 /*********************/
   230 /*********************/
   209 /* B 1.4 - Variables */
   231 /* B 1.4 - Variables */
   210 /*********************/
   232 /*********************/