stage3/array_range_check.cc
changeset 975 3604464aa80e
parent 970 0ede7ca157e2
child 976 619a2b9f6edf
equal deleted inserted replaced
974:a47c2df5ae3d 975:3604464aa80e
   196 	/* Determine the size of the array... */
   196 	/* Determine the size of the array... */
   197 	if        (VALID_CVALUE( int64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) {  
   197 	if        (VALID_CVALUE( int64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) {  
   198 		// do the sums in such a way that no overflow is possible... even during intermediate steps used by compiler!
   198 		// do the sums in such a way that no overflow is possible... even during intermediate steps used by compiler!
   199 		// remember that the result (dimension) is unsigned, while the operands are signed!!
   199 		// remember that the result (dimension) is unsigned, while the operands are signed!!
   200 		// dimension = GET_CVALUE( int64, symbol->upper_limit) - VALID_CVALUE( int64, symbol->lower_limit);
   200 		// dimension = GET_CVALUE( int64, symbol->upper_limit) - VALID_CVALUE( int64, symbol->lower_limit);
   201 		if (GET_CVALUE( int64, symbol->lower_limit) >= 0) {
   201 		if  (GET_CVALUE( int64, symbol->lower_limit)  >   GET_CVALUE( int64, symbol->upper_limit)) {
       
   202 			STAGE3_ERROR(0, symbol, symbol, "Subrange has lower limit (%"PRId64") larger than upper limit (%"PRId64").", GET_CVALUE( int64, symbol->lower_limit), GET_CVALUE( int64, symbol->upper_limit));
       
   203 			dimension = std::numeric_limits< unsigned long long int >::max() - 1; // -1 because it will be incremented at the end of this function!! 
       
   204 		} else if (GET_CVALUE( int64, symbol->lower_limit) >= 0) {
   202 			dimension = GET_CVALUE( int64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit);
   205 			dimension = GET_CVALUE( int64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit);
   203 		} else {
   206 		} else {
   204 			dimension  = -GET_CVALUE( int64, symbol->lower_limit);
   207 			dimension  = -GET_CVALUE( int64, symbol->lower_limit);
   205 			dimension +=  GET_CVALUE( int64, symbol->upper_limit);     
   208 			dimension +=  GET_CVALUE( int64, symbol->upper_limit);     
   206 		}
   209 		}
   207 	} else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE(uint64, symbol->lower_limit)) {
   210 	} else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE(uint64, symbol->lower_limit)) {
   208 		dimension = GET_CVALUE(uint64, symbol->upper_limit) - GET_CVALUE(uint64, symbol->lower_limit); 
   211 		if  (GET_CVALUE(uint64, symbol->lower_limit)  >   GET_CVALUE(uint64, symbol->upper_limit)) {
       
   212 			STAGE3_ERROR(0, symbol, symbol, "Subrange has lower limit (%"PRIu64") larger than upper limit (%"PRIu64").", GET_CVALUE(uint64, symbol->lower_limit), GET_CVALUE(uint64, symbol->upper_limit));
       
   213 			dimension = std::numeric_limits< unsigned long long int >::max() - 1; // -1 because it will be incremented at the end of this function!! 
       
   214 		} else
       
   215 			dimension = GET_CVALUE(uint64, symbol->upper_limit) - GET_CVALUE(uint64, symbol->lower_limit); 
   209 	} else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) {
   216 	} else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) {
       
   217 		// No need to check whether lower_limit > upper_limit, as we only reach this point if lower_limit < 0 (and upper_limit must be >= 0!)
   210 		if (GET_CVALUE( int64, symbol->lower_limit) >= 0) {
   218 		if (GET_CVALUE( int64, symbol->lower_limit) >= 0) {
   211 			dimension = GET_CVALUE(uint64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit);
   219 			dimension = GET_CVALUE(uint64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit);
   212 		} else {
   220 		} else {
   213 			unsigned long long int lower_ull;
   221 			unsigned long long int lower_ull;
   214 			lower_ull  = -GET_CVALUE( int64, symbol->lower_limit);
   222 			lower_ull  = -GET_CVALUE( int64, symbol->lower_limit);
   215 			dimension  =  GET_CVALUE(uint64, symbol->upper_limit) + lower_ull;     
   223 			dimension  =  GET_CVALUE(uint64, symbol->upper_limit) + lower_ull;     
   216 			if (dimension < lower_ull)
   224 			if (dimension < lower_ull)
   217 				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());
   225 				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());
   218 		}
   226 		}
       
   227 	} else if (!VALID_CVALUE(uint64, symbol->upper_limit) && !VALID_CVALUE( int64, symbol->upper_limit)) {
       
   228 		STAGE3_ERROR(0, symbol->upper_limit, symbol->upper_limit, "Subrange upper limit is not a constant value.");
       
   229 		// set dimension to largest possible value so we do not get any further related error messages.
       
   230 		dimension = std::numeric_limits< unsigned long long int >::max() - 1; // -1 because it will be incremented at the end of this function!! 
       
   231 	} else if (!VALID_CVALUE(uint64, symbol->lower_limit) && !VALID_CVALUE( int64, symbol->lower_limit)) {
       
   232 		STAGE3_ERROR(0, symbol->lower_limit, symbol->lower_limit, "Subrange lower limit is not a constant value.");
       
   233 		// set dimension to largest possible value so we do not get any further related error messages.
       
   234 		dimension = std::numeric_limits< unsigned long long int >::max() - 1; // -1 because it will be incremented at the end of this function!! 
   219 	} else {ERROR;}
   235 	} else {ERROR;}
   220 
   236 
   221 	/* correct value for dimension is actually ---> dimension = upper_limit - lower_limit + 1
   237 	/* correct value for dimension is actually ---> dimension = upper_limit - lower_limit + 1
   222 	 * Up to now, we have only determined dimension = upper_limit - lower_limit
   238 	 * Up to now, we have only determined dimension = upper_limit - lower_limit
   223 	 * We must first check whether this last increment will cause an overflow!
   239 	 * We must first check whether this last increment will cause an overflow!