!standard 3.5(39.4/3) 18-01-29 AI12-0244-1/02 !standard 3.5(39.5/3) !standard 3.5(39.12/3) !standard 11.5(17) !class binding interpretation 18-01-11 !status Amendment 1-2012 18-01-29 !status WG9 Approved 16-06-22 !status ARG Approved 11-0-0 18-01-29 !status work item 18-01-11 !status received 17-04-28 !priority Low !difficulty Easy !qualifier Omission !subject Check name for Value attributes !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 subtype of the prefix of the attribute_reference.} The redundant markers should be removed from 11.5(11/2-23), except for the lead-in text. !corrigendum 11.5(17) @drepl @xhang<@xterm Check that a scalar value satisfies a range constraint. Also, for the elaboration of a @fa, check that the @fa (if present) is compatible with the subtype denoted by the @fa. Also, for an @fa, 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.> @dby @xhang<@xterm Check that a scalar value satisfies a range constraint. Also, for the elaboration of a @fa, check that the @fa (if present) is compatible with the subtype denoted by the @fa. Also, for an @fa, 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 subtype of the @fa of the @fa.> !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. ****************************************************************