On 3/16/06, Richard Guenther <[EMAIL PROTECTED]> wrote: > On 3/16/06, Laurent GUERBY <[EMAIL PROTECTED]> wrote: > > On Thu, 2006-03-16 at 10:43 +0100, Richard Guenther wrote: > > > On 3/16/06, Geert Bosch <[EMAIL PROTECTED]> wrote: > > > > > > > > On Mar 16, 2006, at 05:09, Robert Dewar wrote: > > > > > Not quite right. If you have an uninitialized variable, the value is > > > > > invalid and may be out of bounds, but this is a bounded error > > > > > situation, > > > > > not an erroneous program. So the possible effects are definitely NOT > > > > > unbounded, and the use of such values cannot turn a program erroneous. > > > > > (that's an Ada 95 change, this used to be erroneous in Ada 83). > > > > > > > > Actually, that's a good point and raises some potential issues: > > > > if we're never establish the invariant that a value of a type is in > > > > range, we can only use the base range for variables that might be > > > > used uninitialized. Any read of such a variable would then involve > > > > a range check. > > > > > > > > package Uninitialized is > > > > N : Positive; > > > > end Uninitialized; > > > > > > > > with Uninitialized; > > > > procedure Test is > > > > for J in 1 .. Uninitialized.N loop > > > > ... > > > > end loop; > > > > end Test; > > > > > > > > In this case, GCC might replace the loop with > > > > declare > > > > J : Integer := 1; > > > > begin > > > > while J /= Uninitialized.N loop > > > > ... > > > > J := J + 1; > > > > end loop; > > > > end; > > > > > > > > which would be incorrect for N = 0. > > > > > > Uh - what do you expect here?? Does the Ada standard require a > > > out-of-range > > > exception upon the first use of N? > > > > << > > 13.9.1 Data Validity > > > > Bounded (Run-Time) Errors > > > > 9 {invalid representation} {bounded error (cause) [partial]} If the > > representation of a scalar object does not represent a value of the object's > > subtype (perhaps because the object was not initialized), the object is said > > to have an invalid representation. It is a bounded error to evaluate the > > value > > of such an object. {Program_Error (raised by failure of run-time check)} > > {Constraint_Error (raised by failure of run-time check)} If the error is > > detected, either Constraint_Error or Program_Error is raised. Otherwise, > > execution continues using the invalid representation. The rules of the > > language outside this subclause assume that all objects have valid > > representations. The semantics of operations on invalid representations are > > as > > follows: > > > > 9.a Discussion: The AARM is more explicit about what happens when the > > value of the case expression is an invalid representation. > > > > 9.b/2 Ramification: {AI95-00426-01} This includes the result object of > > functions, including the result of Unchecked_Conversion, T'Input, > > and imported functions. > > > > 10 If the representation of the object represents a value of the object's > > type, the value of the type is used. > > > > 11 If the representation of the object does not represent a value of the > > object's type, the semantics of operations on such representations is > > implementation-defined, but does not by itself lead to erroneous or > > unpredictable execution, or to other objects becoming abnormal. > > > > 11.a/2 Implementation Note: {AI95-00426-01} This means that the > > implementation must take care not to use an invalid representation > > in a way that might cause erroneous execution. For instance, the > > exception mandated for case_statements must be raised. Array > > indexing must not cause memory outside of the array to be written > > (and usually, not read either). These cases and similar cases may > > require explicit checks by the implementation. > > >> > > > > So in this case the behaviour is implementation defined, from my reading > > an infinite loop is not contrary to the standard. > > > > > In this case, the frontend needs > > > to insert a proper > > > check. You cannot expect the middle-end to avoid the above > > > transformation, so > > > this is a frontend bug. > > > > Do the ME or the BE have a representation for potentially uninitalized > > variables? > > No. > > > In the following case: > > > > procedure T2 is > > type R is range 1 .. 10; > > type T is array (R) of Integer; > > I : R; > > X : T; > > begin > > X (I) := 0; > > end T2; > > > > The Ada FE will insert an explicit check, as seen when using > > gcc -c -gnatdg t2.adb: > > > > [constraint_error when not (interfaces__unsigned_32!(i) >= 1 and then > > interfaces__unsigned_32!(i) <= 10) "invalid data"] > > > > Will the ME or FE remove the check? > > If you do the check in the base type then it will be only removed if > the compiler > can prove the comparisons are always true. For instance if there is a > preceding > initialization of i to say 3. Also if the basetype is somehow known > to have a value > outside of the range, the constraint error will be raised > unconditionally (but as I > understand there is no way the frontend can produce such knowledge).
Note that gigi needs to use VIEW_CONVERT_EXPR to create a view in the base type for such checks (likewise for the 'Valid case). Now for VRP suppose we have (sorry for the C-ish Ada code ;)) derived uninitialized; if (VIEW_CONVERT_EXPR(base_type, uninitialized) < 0) abort(); now VRP infers a range of 1..10 for uninitialized infered from TYPE_MIN/MAX_VALUE. If VRP wants to propagate ranges through VIEW_CONVERT_EXPRs (which it wants, if the above check should be optimized in case the value is initialized), it needs to exclude somehow range information infered from TYPE_MIN/MAX_VALUE. So, for derived initialized = 1; if (VIEW_CONVERT_EXPR(base_type, uninitialized) < 0) abort(); VRP should be able to remove the test (I guess at the moment VRP simply stops if seeing VIEW_CONVERT_EXPRs). Richard.