Version 1.1 of ai12s/ai12-0244-1.txt

Unformatted version of ai12s/ai12-0244-1.txt version 1.1
Other versions for file ai12s/ai12-0244-1.txt

!standard 3.5(39.4/3)          18-01-11 AI12-0244-1/01
!standard 3.5(39.5/3)
!standard 3.5(39.12/3)
!standard 11.5(17)
!class binding interpretation 18-01-11
!status work item 18-01-11
!status received 17-04-28
!priority Low
!difficulty Easy
!qualifier Omission
!subject
!summary
Add the Value, Wide_Value, and Wide_Wide_Value attributes to the description of Range_Check.
!question
The AARM says that pragma Suppress(Range_Check) will give the permission to suppress checks made as part of the Value attribute. (See AARM 3.5(39.a.1/2)).
However, the description of Range_Check in 11.5(17) does not include anything about the Value attribute, nor does any of the normative wording in 3.5 mention Range_Check.
Is this really a Range_Check? (Yes.)
!recommendation
(See Summary.)
!wording
Modify 11.5(17):
Check that a scalar value satisfies a range constraint. Also, for the elaboration of a subtype_indication, check that the constraint (if present) is compatible with the subtype denoted by the subtype_mark. Also, for an aggregate, check that an index or discriminant value belongs to the corresponding subtype. Also, check that when the result of an operation yields an array, the value of each component belongs to the component subtype.{ Also, for the attributes Value, Wide_Value, and Wide_Wide_Value, check that the given string has the appropriate syntax and value for the base type of the attribute.}
The redundant markers should be removed from 11.5(11/2-23), except for the lead-in text.
!discussion
Tucker Taft, in private communication, said that the original intent was that the index entries for Range_Check, Index_Check, and so on, would provide a definitive list of the various check names. However, the index is not normative.
The description of the check names themselves in 11.5 is marked as "Redundant", but there is no normative definition of the checks anywhere else. Luckily, "Redundant" is itself not normative, so we can consider 11.5 normative. Any missing checks need to be added to this list. Note that we've done that in the past for new checks (for instance, null exclusions were added to 11.5(11/2)).
[Editor's note: I DID NOT check the index to see if any other checks need to be added to 11.5. Any volunteers??]
!ASIS
No ASIS effect.
!ACATS test
!appendix

!topic Does 'Value raise Constraint_Error if suppressed
!reference Ada 2012 RM39.4/3
!from Victor Porton 17-11-09
!keywords Constraint_Error, value
!discussion

It should be explicitly said in the RM if S'Wide_Wide_Value function
necessarily raises Constraint_Error even if suppressed by pragma
Suppress(Range_Check).

GNAT does raise the exception even if suppressed. I consider this the
right behavior as this deals with external data which may be not
guaranteed to conform to our requirements.

****************************************************************

From: Tucker Taft
Sent: Thursday, November 9, 2017  4:04 PM

I am unclear on your rationale here.  Pragma Suppress is only advisory --
a compiler is always free to obey if it is convenient to do so, or to
ignore when it is not convenient.  Why would you want to change that in this
case?  What makes this issue more important than other range checks?

****************************************************************

From: Randy Brukardt
Sent: Thursday, November 9, 2017  4:25 PM

...
> It should be explicitly said in the RM if S'Wide_Wide_Value function 
> necessarily raises Constraint_Error even if suppressed by pragma 
> Suppress(Range_Check).

The AARM explicitly says the reverse.

But (assuming you are talking about the enumeration case - 3.5(39.4/3)), I
do not understand why this is supposedly a Range_Check in the first place.
AARM 39.a.1/2 says that it is a Range_Check because "it doesn't seem
worthwhile to invent a whole new check name just for this weird case, so we
decided to lump it in with Range_Check."

But I don't see anything anywhere else that claims this is a Range_Check. In
particular, none of the reasons listed in 11.5(17) include this case (there's
surely no "range" being violated when the syntax is impossible!).

From that I'd conclude that the RM actually says that this is not one of the
checks that can be suppressed. (AARM notes not being normative, so they don't
mean anything.)

This doesn't seem like something that can be usefully suppressed anyway; my
Value code would most likely just crash if presented with junk syntax, and it
most likely is implemented in a library anyway (so suppression is more work
than it could possibly be worth).

OTOH, people who suppress checks (ANY checks) get what they deserve (garbage),
and it is hard to get too concerned about programmers who purposely write
unsafe code. (I realize some systems suppress checks after using SPARK to
prove that they can't fail, but that is uninteresting in this case as if they
don't fail, whether or not they are actually suppressed is irrelevant to the
execution of the program.)

So I tend to agree with you, other than that no real change seems needed to
the RM. But it seems like a very unimportant point either way.

****************************************************************

From: Victor Porton
Sent: Thursday, November 9, 2017  6:13 PM

> But (assuming you are talking about the enumeration case - 
> 3.5(39.4/3)), I do not understand why this is supposedly a Range_Check 
> in the first place.

It should be 39.5/3.

***************************************************************

From: Randy Brukardt
Sent: Thursday, November 9, 2017  6:36 PM

> It should be 39.5/3.

What should be? The rules apply equally to enumeration and integer cases; it
would be horrible for them to be different.

The part about the syntax being correct surely is not a Range_Check, even for
an Integer. That is what I was objecting to.

The part of 3.5(39.5/3) about the value being in the base range I suppose
should be a range check, but suppressing that check is no more or less
harmless than suppressing any other check. Ada has plenty of text explaining
how invalid scalar values are handled (see 13.9.1), and I don't see any reason
that this one should be special.

So I think my conclusion remains the same: suppressing the syntax part of the
check (for integer or enumerations) is nonsense (and doesn't appear to me to
be supported by the RM wording, either, YMMV on that). The base range check
could (but doesn't have to be) suppressed, and that can't cause any problems
that Suppressing any check can't cause. (If Suppressing checks hurts, then
don't do that!!!).

****************************************************************

From: Victor Porton
Sent: Thursday, November 9, 2017  6:18 PM

> I am unclear on your rationale here.  ...

It should be 39.5/3 instead of 39.4/3. That is it is about integer types.

It is more important than other range check is that it makes EVERY program
which uses Integer'Value erroneous (failing on some input).

However suppressing other range checks (not in I/O) may keep a program not
erroneous (despite having no checks).

So 'Value is special, because if it is suppressed it GUARANTELY makes the
program erroneous. We don't want to produce an erroneous program, in any case!

****************************************************************

From: Randy Brukardt
Sent: Thursday, November 9, 2017  7:35 PM

...
> It is more important than other range check is that it makes EVERY 
> program which uses Integer'Value erroneous (failing on some input).

Huh? A suppressed check is only erroneous if the check would have failed (that
is, raised Constraint_Error). The term is "erroneous execution" after all; a
*program* can't be erroneous, only a specific execution.

> However suppressing other range checks (not in I/O) may keep a program 
> not erroneous (despite having no checks).
> 
> So 'Value is special, because if it is suppressed it GUARANTELY makes 
> the program erroneous. We don't want to produce an erroneous program, 
> in any case!

So this is nonsense. The program execution is only erroneous if there actually
is an input given to the program which would have raised Constraint_Error.
There certainly exist values that could be given to Integer'Value which do not
raise Constraint_Error, therefore the program cannot possibly be guaranteed to
be erroneous, even with the check suppressed.

You seem to want guarantees about validation of values, but 'Value alone is
not the way to get such guarantees. Besides, if you really want such
guarantees, DO NOT SUPPRESS CHECKS!!! You can always use
Unsuppress(Range_Check) in an inner scope to ensure that a given subprogram
doesn't have checks suppressed. That makes more sense than treating the routine
you want to use for validation specially, which doesn't help anyone else using
some other technique for value validation.

****************************************************************

From: Victor Porton
Sent: Friday, November 10, 2017  8:12 AM

By saying that a program is erroneous, I meant that its execution can be made
erroneous by some input data.

In this sense EVERY program which takes 'Value on input data is erroneous.

I do not want a program to be erroneous in the above sense.

****************************************************************

From: Bob Duff
Sent: Friday, November 10, 2017  10:44 AM

> By saying that a program is erroneous, I meant that its execution can 
> be made erroneous by some input data.

That's not how the Ada RM defines "erroneous".
I think it's better to stick with the RM meanings in discussions like this,
especially when it comes to "erroneous", which is confusing enough as it is.

> In this sense EVERY program which takes 'Value on input data is 
> erroneous.

I think you mean "IF CHECKS ARE SUPPRESSED, then every program that takes
'Value of input data can have erroneous execution for some inputs."  That's
true, but it's true for all checks -- 'Value is not special in this regard.
If you say X+1, and X comes from input data, then it might overflow. And if
checks are suppressed, execution is then erroneous.

You're right that it is unwise to suppress checks that are checking input
data.  That's what pragma Unsuppress is for.  The compiler has no way to know
what data is input data.

There's really nothing broken here, so ARG is not going to change the rules
for check suppression for 'Value. You should use Unsuppress when checks apply
to input data.

> I do not want a program to be erroneous in the above sense.

****************************************************************

Questions? Ask the ACAA Technical Agent