stage3/array_range_check.cc
changeset 1101 f7a0e962650d
parent 1041 56ebe2a31b5b
equal deleted inserted replaced
1099:cdb045e8be20 1101:f7a0e962650d
   133       return;
   133       return;
   134 
   134 
   135     /* Check lower limit */
   135     /* Check lower limit */
   136     if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE( int64, dimension->lower_limit))
   136     if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE( int64, dimension->lower_limit))
   137       if ( GET_CVALUE( int64, l->get_element(i)) < GET_CVALUE( int64, dimension->lower_limit) )
   137       if ( GET_CVALUE( int64, l->get_element(i)) < GET_CVALUE( int64, dimension->lower_limit) )
   138       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRId64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)); continue;}
   138       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %" PRId64 ", should be >= %" PRId64 ").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)); continue;}
   139 
   139 
   140     if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->lower_limit))
   140     if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->lower_limit))
   141       if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->lower_limit), GET_CVALUE( int64, l->get_element(i))) > 0 )
   141       if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->lower_limit), GET_CVALUE( int64, l->get_element(i))) > 0 )
   142       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRIu64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
   142       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %" PRId64 ", should be >= %" PRIu64 ").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
   143 
   143 
   144     if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->lower_limit))
   144     if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->lower_limit))
   145       if ( GET_CVALUE(uint64, l->get_element(i))   <  GET_CVALUE(uint64, dimension->lower_limit))
   145       if ( GET_CVALUE(uint64, l->get_element(i))   <  GET_CVALUE(uint64, dimension->lower_limit))
   146       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRIu64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
   146       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %" PRIu64 ", should be >= %" PRIu64 ").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
   147 
   147 
   148     if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE( int64, dimension->lower_limit))
   148     if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE( int64, dimension->lower_limit))
   149       if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)) < 0 )
   149       if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)) < 0 )
   150       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRId64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)); continue;}
   150       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %" PRIu64 ", should be >= %" PRId64 ").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)); continue;}
   151 
   151 
   152     /* Repeat the same check, now for upper limit */
   152     /* Repeat the same check, now for upper limit */
   153     if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE( int64, dimension->upper_limit))
   153     if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE( int64, dimension->upper_limit))
   154       if ( GET_CVALUE( int64, l->get_element(i))   >  GET_CVALUE( int64, dimension->upper_limit))
   154       if ( GET_CVALUE( int64, l->get_element(i))   >  GET_CVALUE( int64, dimension->upper_limit))
   155       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRId64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)); continue;}
   155       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %" PRId64 ", should be <= %" PRId64 ").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)); continue;}
   156 
   156 
   157     if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->upper_limit))
   157     if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->upper_limit))
   158       if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->upper_limit), GET_CVALUE( int64, l->get_element(i))) < 0 )
   158       if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->upper_limit), GET_CVALUE( int64, l->get_element(i))) < 0 )
   159       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRIu64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE(uint64, dimension->upper_limit)); continue;}
   159       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %" PRId64 ", should be <= %" PRIu64 ").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE(uint64, dimension->upper_limit)); continue;}
   160 
   160 
   161     if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->upper_limit))
   161     if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->upper_limit))
   162       if ( GET_CVALUE(uint64, l->get_element(i))   >  GET_CVALUE(uint64, dimension->upper_limit))
   162       if ( GET_CVALUE(uint64, l->get_element(i))   >  GET_CVALUE(uint64, dimension->upper_limit))
   163       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRIu64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE(uint64, dimension->upper_limit)); continue;}
   163       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %" PRIu64 ", should be <= %" PRIu64 ").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE(uint64, dimension->upper_limit)); continue;}
   164       
   164       
   165     if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE( int64, dimension->upper_limit))
   165     if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE( int64, dimension->upper_limit))
   166       if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)) > 0 )
   166       if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)) > 0 )
   167       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRId64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)); continue;}
   167       {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %" PRIu64 ", should be <= %" PRId64 ").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)); continue;}
   168       
   168       
   169   }
   169   }
   170 }
   170 }
   171 
   171 
   172 
   172 
   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)  >   GET_CVALUE( int64, symbol->upper_limit)) {
   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));
   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!! 
   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) {
   204 		} else if (GET_CVALUE( int64, symbol->lower_limit) >= 0) {
   205 			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);
   206 		} else {
   206 		} else {
   207 			dimension  = -GET_CVALUE( int64, symbol->lower_limit);
   207 			dimension  = -GET_CVALUE( int64, symbol->lower_limit);
   208 			dimension +=  GET_CVALUE( int64, symbol->upper_limit);     
   208 			dimension +=  GET_CVALUE( int64, symbol->upper_limit);     
   209 		}
   209 		}
   210 	} 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)) {
   211 		if  (GET_CVALUE(uint64, symbol->lower_limit)  >   GET_CVALUE(uint64, symbol->upper_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));
   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!! 
   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
   214 		} else
   215 			dimension = GET_CVALUE(uint64, symbol->upper_limit) - GET_CVALUE(uint64, symbol->lower_limit); 
   215 			dimension = GET_CVALUE(uint64, symbol->upper_limit) - GET_CVALUE(uint64, symbol->lower_limit); 
   216 	} 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!)
   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!)