This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] for PRs 27639 and 26719


> How do subtypes wrap, if at all?  If you have an unsigned [0, 7], what
> is the result of u + 8?  What is the result of u + 256 (if the base type
> was unsigned char)?  Is it defined?

Hi Richard, in Ada arithmetic on subtypes is defined by: convert to base
type, perform arithmetic, convert back.  The language requires a check
that the value is in the range of the subtype, with an exception being
raised if not (the Ada front-end inserts this check except when it can
prove that it is not needed).

(A) u + 8.  The front-end would generate:

   tmp = ((unsigned char) u) + 8;
   if (tmp > 7)
      goto raise_exception;
   u = (subtype) tmp;

VRP could deduce that tmp>7 is always true and the final code would be:

   goto raise_exception;

So the front-end will never generate such an expression, in fact it will
never generate any arithmetic directly in u at all.  However, in general
the compiler (in this case the back-end) could reasonably generate
arithmetic directly in u if it could prove that the component expressions
and the result are in the range of the subtype.  So if you ever see an
expression like:
	u = u + 8;
then that should imply that the compiler has proved that u+8 is in the range
of the subtype (which is not the case here).  Also, here "8" is also not in
the range of the subtype, which is another reason why you can't get this
expression for this subtype.

(B) u + 256.  Since 256 does not even belong to the type unsigned char,
this expression cannot occur.

(C) u / 2.  The front-end would generate:

   unsigned char tmp;
   tmp = ((unsigned char) u) / 2;
   if (tmp > 7)
      goto raise_exception;
   u = (subtype) tmp;

VRP would deduce that tmp>7 is always false and the code would become:

   unsigned char tmp;
   tmp = ((unsigned char) u) / 2;
   u = (subtype) tmp;

At this point the back-end could reasonably replace this with:
   u = u / 2;

(D) u + 4.  The front-end code

   tmp = ((unsigned char) u) + 4;
   if (tmp > 7)
      goto raise_exception;
   u = (subtype) tmp;

could be simplified to:

   if (u > 3)
	goto raise_exception;
   tmp = ((unsigned char) u) + 4;
   u = (subtype) tmp;

which could reasonably be turned into

   if (u > 3)
	goto raise_exception;
   u = u + 4;

Here u = u + 4 means (1) arithmetic is the same as in the base type,
and (2) the compiler has proved that u+4 is in the range of the subtype.

Best wishes,

Duncan.

PS: A variable of a subtype can contain an out of range value (for example
because it was uninitialized), but then making any use of that value means
that the program erroneous, much like for use of uninitialized variables.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]