Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2019-07

Minor debate with ISO standard on case blocks

28 messages · 9 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

J. Gareth Moreton

Hi everyone,

So there's been an issue raised
<https://bugs.freepascal.org/view.php?id=35905> in regards to ISO compliance with case blocks (when under $mode iso).  Currently, a compiler error is raised if a case block does not have exhaustive coverage for the input type (it's a warning on other modes).

According to ISO7185 <http://pascal-central.com/docs/iso7185.pdf>, page 55, section 6.8.3.5:

"On execution of the case-statement the case-index shall be evaluated. That value shall then specify execution of the statement of the case-list-element closest-containing thecase-constant denoting that value. One of the case-constants shall be equal to the value of the case-index upon entry to the case-statement; otherwise, it shall be an error."

Given it says "on execution", it implies this all occurs at run-time, especially as 'case-index' is usually a variable or otherwise non-deterministic at compile-time, hence the error should be a run-time error, not a compile-time error.  I think the issue is that FPC won't compile some well-known ISO Pascal code
<https://bugs.freepascal.org/view.php?id=35859> because some of the case blocks don't exhaustively cover all inputs (which itself might be a sign of bad programming, but could be justified if said values are determined to be logically impossible, in which case the else blocks should contain assertions or internal errors).

Just interpreting the standard, I think that the error should be run-time, not compile-time (although definitely keep the warning).  That's just my take on it though.  If it is to be changed, it should be simple enough by configuring the 'elselabel' field to point to an error-raising routine rather than 'endlabel' (which occurs if there's no else block).

Gareth aka. Kit

---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

Reply by email

J. Gareth Moreton
to J. Gareth Moreton

As someone on the issue pointed out... on page 2, section 3.1:

3.1 Error

A violation by a program of the requirements of this International Standard that a processor is permitted to leave undetected.

NOTES

1. If it is possible to construct a program in which the violation or non-violation of this International Standard requires knowledge of the data read by the program or the implementation definition of implementation-defined features, then violation of that requirement is classified as an error. Processors may report on such violations of the requirement without such knowledge, but there always remain some cases that require execution, simulated execution, or proof procedures with the required knowledge. Requirements that can be verified without such knowledge are not classified as errors.

2. Processors should attempt the detection of as many errors as possible, and to as complete a degree as possible. Permission to omit detection is provided for implementations in which the detection would be an excessive burden.

----

I guess that leaves the question up in the air because FPC is reporting an ISO violation without knowledge of program input, but speculating that a particular input might not be covered.

Gareth aka. Kit

J. Gareth Moreton wrote 50 lines
Hi everyone, So there's been an issue raised <https://bugs.freepascal.org/view.php?id=35905> in regards to ISO compliance with case blocks (when under $mode iso).  Currently, a compiler error is raised if a case block does not have exhaustive coverage for the input type (it's a warning on other modes). According to ISO7185 <http://pascal-central.com/docs/iso7185.pdf>, page 55, section 6.8.3.5: "On execution of the case-statement the case-index shall be evaluated. That value shall then specify execution of the statement of the case-list-element closest-containing thecase-constant denoting that value. One of the case-constants shall be equal to the value of the case-index upon entry to the case-statement; otherwise, it shall be an error." Given it says "on execution", it implies this all occurs at run-time, especially as 'case-index' is usually a variable or otherwise non-deterministic at compile-time, hence the error should be a run-time error, not a compile-time error.  I think the issue is that FPC won't compile some well-known ISO Pascal code <https://bugs.freepascal.org/view.php?id=35859> because some of the case blocks don't exhaustively cover all inputs (which itself might be a sign of bad programming, but could be justified if said values are determined to be logically impossible, in which case the else blocks should contain assertions or internal errors). Just interpreting the standard, I think that the error should be run-time, not compile-time (although definitely keep the warning).  That's just my take on it though.  If it is to be changed, it should be simple enough by configuring the 'elselabel' field to point to an error-raising routine rather than 'endlabel' (which occurs if there's no else block). Gareth aka. Kit <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> Virus-free. www.avast.com <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

Reply by email

thaddy
to J. Gareth Moreton

Telling.

I took the trouble to look up the case statement in a random selection of about 30 instruction manuals, books and magazines about Pascal from my personal library (only a few pretend to be ISO compliant or mention the standard, though. These beasts are rare) and some compilers. I can not find 1! implementation that tries to do what FPC trunk currently does.

I am really passionate about this. The quote below seems to suggest that the behavior in 3.0.4 was acceptable after all.
That said: the suggestion by Gareth to issue a warning at compile time and a run-time error when an ordinal is used that has no case label seems to be much closer to what the 7185:1990 standard actually describes.

According to what I found there is no smoking gun: I could not find any implementation or reference from any reputable source that implements the case statement in the way that is implemented in trunk: compile time error when not all of the ordinal range for the case are processed. It simply does not exist as far as I am concerned, unless someone can convince be by a reputable source that such implementation exists elsewhere.

I strongly object against the current implementation and I believe it to rely on false premises.

Thaddy

J. Gareth Moreton wrote 25 lines
As someone on the issue pointed out... on page 2, section 3.1: 3.1 Error A violation by a program of the requirements of this International Standard that a processor is permitted to leave undetected. NOTES 1. If it is possible to construct a program in which the violation or non-violation of this International Standard requires knowledge of the data read by the program or the implementation definition of implementation-defined features, then violation of that requirement is classified as an error. Processors may report on such violations of the requirement without such knowledge, but there always remain some cases that require execution, simulated execution, or proof procedures with the required knowledge. Requirements that can be verified without such knowledge are not classified as errors. 2. Processors should attempt the detection of as many errors as possible, and to as complete a degree as possible. Permission to omit detection is provided for implementations in which the detection would be an excessive burden. ----

Reply by email

thaddy
to J. Gareth Moreton: As someone on the issue pointed out... on page 2, section 3.1: 3.1 Error A violation by a…
J. Gareth Moreton wrote
As someone on the issue pointed out... on page 2, section 3.1: 3.1 Error

I have added this to the bug report. Consider that here all possible case labels are implemented, the compiler still throws a compile time error.
That means the implementation is wrong anyway.

{$mode ISO}
program isobug(infile,outfile);
type
   operator = (plus, minus, times);
var
   x:integer;
   o:operator = plus;
begin
   x:=1;
   case o of
     plus : x := x;  // all
     minus : x := x; // possible
     times : x := x; // cases
   end;
end.

The easy way out seems to revert to the 3.0.4 implementation given the section mentioned.
Gareth's suggestion would be nice to have, though.

Reply by email

Michael Van Canneyt
to J. Gareth Moreton: So there's been an issue raised <https://bugs.freepascal.org/view.php?id=35905> in…
J. Gareth Moreton wrote 33 lines
Hi everyone, So there's been an issue raised <https://bugs.freepascal.org/view.php?id=35905> in regards to ISO compliance with case blocks (when under $mode iso).  Currently, a compiler error is raised if a case block does not have exhaustive coverage for the input type (it's a warning on other modes). According to ISO7185 <http://pascal-central.com/docs/iso7185.pdf>, page 55, section 6.8.3.5: "On execution of the case-statement the case-index shall be evaluated. That value shall then specify execution of the statement of the case-list-element closest-containing thecase-constant denoting that value. One of the case-constants shall be equal to the value of the case-index upon entry to the case-statement; otherwise, it shall be an error." Given it says "on execution", it implies this all occurs at run-time, especially as 'case-index' is usually a variable or otherwise non-deterministic at compile-time, hence the error should be a run-time error, not a compile-time error.  I think the issue is that FPC won't compile some well-known ISO Pascal code <https://bugs.freepascal.org/view.php?id=35859> because some of the case blocks don't exhaustively cover all inputs (which itself might be a sign of bad programming, but could be justified if said values are determined to be logically impossible, in which case the else blocks should contain assertions or internal errors). Just interpreting the standard, I think that the error should be run-time, not compile-time (although definitely keep the warning).  That's just my take on it though.  If it is to be changed, it should be simple enough by configuring the 'elselabel' field to point to an error-raising routine rather than 'endlabel' (which occurs if there's no else block).

I tend to agree with your reading of the spec.

Michael.

Reply by email

Michael Van Canneyt
to thaddy: Telling. I took the trouble to look up the case statement in a random selection of about…
thaddy wrote 13 lines
Telling. > > NOTES > > 1. If it is possible to construct a program in which the violation or > non-violation of this International Standard requires knowledge of the > data read by the program or the implementation definition of > implementation-defined features, then violation of that requirement is > classified as an error. Processors may report on such violations of > the requirement without such knowledge, but there always remain some > cases that require execution, simulated execution, or proof procedures > with the required knowledge. Requirements that can be verified without > such knowledge are not classified as errors.

Hm.

Even after reading this 5 times, I still am not sure I understand the above. The people who wrote this must have been either extraordinary geniuses, or very confused minds.

Or else they wanted to give a befriended unemployed lawyer some work. But anyone writing such a paragraph deserves to be unemployed... ;)

How you're suppsed to construct a working & compliant 'processor' (I assume this means compiler or interpreter or somesuch) after reading this is a mystery to me.

Michael.

Reply by email

thaddy
to Michael Van Canneyt

I submitted a patch so that iso mode behaves like extended pascal mode. i.e.
The compile time error is gone (also in the case I showed to be a true bug)
And a run-time error is issued as per extendedpascal.

Solves most problems I have with the "feature" and existing code written in iso mode compiles again.

Reply by email

thaddy
to Michael Van Canneyt: I tend to agree with your reading of the spec. Michael.
Michael Van Canneyt wrote 13 lines
> Just interpreting the standard, I think that the error should be > run-time, not compile-time (although definitely keep the warning).  > That's just my take on it though.  If it is to be changed, it should > be simple enough by configuring the 'elselabel' field to point to an > error-raising routine rather than 'endlabel' (which occurs if there's > no else block). I tend to agree with your reading of the spec. Michael. _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

I solved it by having iso use the same codepath as extended pascal

Reply by email

J. Gareth Moreton
to Michael Van Canneyt: Hm. Even after reading this 5 times, I still am not sure I understand the above. The…

Yeah, I don't find that description clear either.  One shouldn't have to be a lawyer in order to decrypt such standards!

Of course, FPC can follow its own standard, but it should be one that everyone agrees on.  While I think we shouldn't live in the shadow of Delphi or be jammed in the realm of backwards compatibility, I'm a bit wary if there are quirks or errors that might otherwise cause people to back away from FPC rather than adapt their code to conform to it.

But just from a practicality point of view, I think a run-time error is better in this instance because you may be able to justify a particular input value not being possible, and so not need to add code for it in your case block, but if such a value ends up reaching the case block anyway, then you deserve to endure a run-time error because it means you haven't covered it properly.

Speaking of books and documentation, what's out there for Free Pascal in particular?

Gareth aka. Kit

P.S. I like to think my own design specs are a lot clearer than that ISO!

Michael Van Canneyt wrote 37 lines
On Tue, 30 Jul 2019, thaddy wrote: > Telling. >> >> NOTES >> >> 1. If it is possible to construct a program in which the violation or >> non-violation of this International Standard requires knowledge of the >> data read by the program or the implementation definition of >> implementation-defined features, then violation of that requirement is >> classified as an error. Processors may report on such violations of >> the requirement without such knowledge, but there always remain some >> cases that require execution, simulated execution, or proof procedures >> with the required knowledge. Requirements that can be verified without >> such knowledge are not classified as errors. Hm. Even after reading this 5 times, I still am not sure I understand the above. The people who wrote this must have been either extraordinary geniuses, or very confused minds. Or else they wanted to give a befriended unemployed lawyer some work. But anyone writing such a paragraph deserves to be unemployed... ;) How you're suppsed to construct a working & compliant 'processor' (I assume this means compiler or interpreter or somesuch) after reading this is a mystery to me. Michael. _______________________________________________ fpc-devel maillist  -  https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

Reply by email

Martin Frb
to Michael Van Canneyt: Hm. Even after reading this 5 times, I still am not sure I understand the above. The…
Michael Van Canneyt wrote 30 lines
On Tue, 30 Jul 2019, thaddy wrote: > Telling. >> >> NOTES >> >> 1. If it is possible to construct a program in which the violation or >> non-violation of this International Standard requires knowledge of the >> data read by the program or the implementation definition of >> implementation-defined features, then violation of that requirement is >> classified as an error. Processors may report on such violations of >> the requirement without such knowledge, but there always remain some >> cases that require execution, simulated execution, or proof procedures >> with the required knowledge. Requirements that can be verified without >> such knowledge are not classified as errors. Hm. Even after reading this 5 times, I still am not sure I understand the above. The people who wrote this must have been either extraordinary geniuses, or very confused minds. Or else they wanted to give a befriended unemployed lawyer some work. But anyone writing such a paragraph deserves to be unemployed... ;) How you're suppsed to construct a working & compliant 'processor' (I assume this means compiler or interpreter or somesuch) after reading this is a mystery to me.

Well if we make the following substitutions (to specialize the statement for the case of fpc)

processor = compiler
error = run time error

Then the firsts sentence:
    "If it is possible to construct a program
    in which the violation (*or non-violation*) of this International Standard
    requires knowledge of the data read by the program     (*   or the implementation definition of implementation-defined features,  *)
    then violation of that requirement is classified as an error. "

Says: if reading the source does not show if the data will be correct, then none correct data shall be a run time error

    "Compiler may report on such violations of
    the requirement without such knowledge"

"such knowlededge" = knowing the data read
If the compiler can say the data will not be correct, then it may report at compile time.

   " but there always remain some cases
     that require execution, simulated execution, or proof procedures      with the required knowledge."

Not all cases can be (reasonable) detected at compile time

     " Requirements that can be verified without       such knowledge are not classified as errors. "

(probably?): violations detected at compile time, are not (run time?) errors.

-------------------------------------------------------------- So if the standard did say, that all values in the defined range of the type of the variable (or result type of the expression in the case) must have an entry in the case list, then the compiler is allowed to bail out during compilation.

But:
"On execution of the case-statement the case-index shall be evaluated. That value shall then specify execution of the statement of the case-list-element closest-containing thecase-constant denoting that value. One of the case-constants shall be equal to the value of the case-index upon entry to the case-statement; otherwise, it shall be an error."

Only says, that the values that actually occur at runtime, must be present. It does not say that the range of the type must be fully present.

if boolval  false then
   case boolval of
      true: ;
   end;

Is therefore valid. Even though the case has no entry for false.

Reply by email

thaddy
to J. Gareth Moreton: Yeah, I don't find that description clear either.  One shouldn't have to be a lawyer in…
J. Gareth Moreton wrote 23 lines
Yeah, I don't find that description clear either.  One shouldn't have to be a lawyer in order to decrypt such standards! Of course, FPC can follow its own standard, but it should be one that everyone agrees on.  While I think we shouldn't live in the shadow of Delphi or be jammed in the realm of backwards compatibility, I'm a bit wary if there are quirks or errors that might otherwise cause people to back away from FPC rather than adapt their code to conform to it. But just from a practicality point of view, I think a run-time error is better in this instance because you may be able to justify a particular input value not being possible, and so not need to add code for it in your case block, but if such a value ends up reaching the case block anyway, then you deserve to endure a run-time error because it means you haven't covered it properly. Speaking of books and documentation, what's out there for Free Pascal in particular? Gareth aka. Kit P.S. I like to think my own design specs are a lot clearer than that ISO!

Efforts to try and be exact often fail.
Natural language is way to expressive for human beings to achieve exactness.
Otherwise we would have a compiler for it ;)

Reply by email

Michael Van Canneyt
to Martin Frb: Well if we make the following substitutions (to specialize the statement for the case of…
Martin Frb wrote 9 lines
> How you're suppsed to construct a working & compliant 'processor' (I assume > this means compiler or interpreter or somesuch) after reading this is a > mystery to me. Well if we make the following substitutions (to specialize the statement for the case of fpc) processor = compiler error = run time error

Here we go:

I had assumed error = processor error (= compiler error for FPC) Because "processors may report on such errors" for me implies the "error" is detected and reported during processing (=compiling): nowhere it is said that a processor creates an executable. (maybe earlier in the text it does, but I don't know that)

But other than that, I mostly agree with your reading of the text.

Michael.

Reply by email

Marco Borsari
to thaddy: Telling. I took the trouble to look up the case statement in a random selection of about…
Show quoted text 7 lines
According to what I found there is no smoking gun: I could not find any implementation or reference from any reputable source that implements the case statement in the way that is implemented in trunk: compile time error when not all of the ordinal range for the case are processed. It simply does not exist as far as I am concerned, unless someone can convince be by a reputable source that such implementation exists elsewhere.

Pascal-S of Wirth does it.

Marco Borsari

Simplex sigillum veri

Reply by email

Paul Breneman
to J. Gareth Moreton: So there's been an issue raised <https://bugs.freepascal.org/view.php?id=35905> in…

This message thread has been interesting to read.

I just realized today that I dealt with similar issues in Delphi 19 years ago. This is discussed in the good Microsoft Press book *Code Complete* by Steve McConnell. Using the default else block of a case statement to show a program error message is exactly what is recommended on pages 319-320 (and the same thing for repeated if statements on page 316). I don't know if this directly applies, but it was fun to renew a few brain cells by looking at old emails.

If I add an enumerated type and forget to update some of my code, I'd like to get an error message when the unchanged code is run.

Regards,
Paul
www.ControlPascal.com

Reply by email

thaddy
to Marco Borsari: On Tue, 30 Jul 2019 06:38:56 +0200 Pascal-S of Wirth does it. Marco Borsari Simplex…
Marco Borsari wrote 16 lines
On Tue, 30 Jul 2019 06:38:56 +0200 thaddy wrote: > According to what I found there is no smoking gun: I could not find > any > implementation or reference from any reputable source that implements > the case statement in the way that is implemented in trunk: compile > time > error when not all of the ordinal range for the case are processed. It > simply does not exist as far as I am concerned, unless someone can > convince be by a reputable source that such implementation exists > elsewhere. Pascal-S of Wirth does it. Marco Borsari

I just compiled pascal-s (Moore's iso version, because that's the relevant one) but did not run it yet with my patch. It fails at run-time or compile-time?
It is an interpreter/p-code system, so has a greater level of freedom. Note iso7158 is based on Wirth's but Wirth's version is not iso compliant.

Reply by email

thaddy
to Paul Breneman: This message thread has been interesting to read. I just realized today that I dealt with…
Paul Breneman wrote 19 lines
This message thread has been interesting to read. I just realized today that I dealt with similar issues in Delphi 19 years ago. This is discussed in the good Microsoft Press book *Code Complete* by Steve McConnell. Using the default else block of a case statement to show a program error message is exactly what is recommended on pages 319-320 (and the same thing for repeated if statements on page 316). I don't know if this directly applies, but it was fun to renew a few brain cells by looking at old emails. If I add an enumerated type and forget to update some of my code, I'd like to get an error message when the unchanged code is run. Regards, Paul www.ControlPascal.com _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

I actually hope Scott Franco reads this (a.k.a Scott Moore). He knows a lot about the standards and developed several iso compliant interpreters/p-code compilers.

Reply by email

Stefan Glienke
to Paul Breneman: This message thread has been interesting to read. I just realized today that I dealt with…

Actually I prefer a compiler error/warning on such cases - so being able to write an exhaustive case is a very good option over eventually getting runtime errors - oh, yeah we all have exhaustive unit tests don't we? ;)

TypeScript for example has the never type which can be used to write a compiletime safe exhaustive switch statement.

Show quoted text 22 lines
On 30 July 2019 at 12:26 Paul Breneman wrote: This message thread has been interesting to read. I just realized today that I dealt with similar issues in Delphi 19 years ago. This is discussed in the good Microsoft Press book *Code Complete* by Steve McConnell. Using the default else block of a case statement to show a program error message is exactly what is recommended on pages 319-320 (and the same thing for repeated if statements on page 316). I don't know if this directly applies, but it was fun to renew a few brain cells by looking at old emails. If I add an enumerated type and forget to update some of my code, I'd like to get an error message when the unchanged code is run. Regards, Paul www.ControlPascal.com _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

thaddy
to thaddy: Efforts to try and be exact often fail. Natural language is way to expressive for human…

Scott Franco a.k.a. Moore says this, what makes sense, in his manual "Rules of ISO 7185":
==========================
Case statement
The case statement defines an action to be executed on each of the values of an ordinal:

case x of
   c1: statement;
   c2: statement;
   ...

end;
The "selector" is an expression that must result in an ordinal type. Each of the "case labels" must be type compatible with the selector. The case statement will execute one, and only one, statement that matches the current selector value. If the selector matches none of the cases, then an error results. It is NOT possible to assume that execution simply continues if none of the cases are matched. A case label MUST match the value of the selector.
==========================

So the core is that his interpretation is: selector - on use - *must* match an existing label. Ergo not the ordinal type but its value determines if it is an error or not.
FPC currently has it the other way around: if the case has insufficient processing for ALL possible values for the selector it already throws a compile-time error.
That's in my opinion the wrong interpretation.

Reply by email

Sven Barth
to thaddy: I have added this to the bug report. Consider that here all possible case labels are…

thaddy schrieb am Di., 30. Juli 2019, 10:04:

Show quoted text 30 lines
On 2019-07-30 01:43, J. Gareth Moreton wrote: > As someone on the issue pointed out... on page 2, section 3.1: > > 3.1 Error I have added this to the bug report. Consider that here all possible case labels are implemented, the compiler still throws a compile time error. That means the implementation is wrong anyway. {$mode ISO} program isobug(infile,outfile); type operator = (plus, minus, times); var x:integer; o:operator = plus; begin x:=1; case o of plus : x := x; // all minus : x := x; // possible times : x := x; // cases end; end. The easy way out seems to revert to the 3.0.4 implementation given the section mentioned. Gareth's suggestion would be nice to have, though.

That's definitely a bug, cause the same code (with "operator" changed to "op") compiles in mode ObjFPC without any warning or error.

Regards,
Sven

Reply by email

thaddy
to Sven Barth
Sven Barth wrote 45 lines
thaddy schrieb am Di., 30. Juli 2019, 10:04: > On 2019-07-30 01:43, J. Gareth Moreton wrote: >> As someone on the issue pointed out... on page 2, section 3.1: >> >> 3.1 Error > > I have added this to the bug report. Consider that here all possible > > case labels are implemented, the compiler still throws a compile > time > error. > That means the implementation is wrong anyway. > > {$mode ISO} > program isobug(infile,outfile); > type > operator = (plus, minus, times); > var > x:integer; > o:operator = plus; > begin > x:=1; > case o of > plus : x := x; // all > minus : x := x; // possible > times : x := x; // cases > end; > end. > > The easy way out seems to revert to the 3.0.4 implementation given > the > section mentioned. > Gareth's suggestion would be nice to have, though. That's definitely a bug, cause the same code (with "operator" changed to "op") compiles in mode ObjFPC without any warning or error. Regards, Sven > _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Yes, it is a bug, but note the case handling in mode objfpc (all modes except macpas, iso and extended) differs.
It should only error out if the selector value has no case label. Extended Pascal then throws a run-time error.
The other modes, like objfpc, silently continue.
It should not error out at all at compile time.
I provided a patch that makes the iso behavior equal to the extended pascal behavior.
This solves both the above issue and the compile time vs run time error.

Reply by email

Martok
to J. Gareth Moreton: So there's been an issue raised <https://bugs.freepascal.org/view.php?id=35905> in…

If you want something a bit more clear, try ISO/IEC 10206 (Extended Pascal). They split up errors and dynamic violations, which helps make the point clearer.

Basically, a "Processor" is sort of an interpreter that first validates the complete program and then activates the program block, "execution" in the interpreter is not the same as actual "activation" of the user program. The ability to save the object code (aka "compile") is completely orthogonal. A violation is generally anything where the input does not validate as a known-good program:

- does not depend on data:
=> generic Violation (ie. syntax error)
- depends on data:
- decidable without computation
=> Error (Type Errors)
- decidable with potentially complex computation
=> dynamic-violation (expression results)

Some examples from Annex D:
"""It is an error if the value of any actual value parameter is assignment-compatibility-erroneous with respect to the type possessed by the corresponding formal-parameter."""
=> The parameters used in a call must be compatible to the declared parameters. This is just a static typecheck.

"""It is a dynamic-violation if the smallest value of a subrange-type is greater than the largest value of the subrange-type when either subrange-bound is not nonvarying or contains a discriminant-identier.""" => The bounds can be expressions, and therefore may not be trivially obained. The need for "compile-time" execution makes this a dynamic-violation.

"""When either dispose(q) or dispose(q,k1,...,km) is activated, it is an error if q has a nil-value or is undefined."""
=> Requires data, but the check is trivial and in constant time, therefore it's an error.

Note that dynamic-violation is still not necessarily a "runtime-error", just that it cannot be validated without computation that cannot be guaranteed to be O(1).

In any case, that only really means that a program where that can happen is not in conformance with the abstract level of the ISO. The Processor can choose what to do about that (paraphrased from 5.1):
a) dynamic-violation:
1) report to the user
continue preparation
but: refuse execution (cf. emit a Warning in -Sew)
2) detect at runtime
terminate program (cf. RunError)
b) Error:
1) same as above
2) leave unhandled, but have a note in the documentation (wtf?)

6.9.3.5 says about the issue at hand:
"""On execution of the case-statement, the case-index shall be evaluated. If a case-range closest-contained by a case-constant-list of a case-list-element of the case-statement denotes that value, the statement of the case-list-element shall be executed; otherwise, if a case-statement-completer occurs in the case-statement, the statement-sequence of the case-statement- completer shall be executed; otherwise, it shall be a dynamic-violation.""" (The case-statement-completer is the 'otherwise' clause)

I have opinions on what that means for when the result of "the case-index shall be evaluated" is already in undetected violation (just apply SQL NULL-type logic to the above), but that's not the point here.

Of course, if you wanted a run-time error you would need to insert a run-time check, and 'some people' seemed to be hell-bent on saving these 2 cycles at any cost.

The patch to switch from option a1) to a2) would be straightforward, fix 32079 and insert a default otherwise clause that raises a RunError in -Miso. But the question is again, does Freepascal actually aim to be compliant with anything, or just have a compatible syntax and do its own thing from there?

Best,

Sebastian

J. Gareth Moreton wrote 47 lines
Hi everyone, So there's been an issue raised <https://bugs.freepascal.org/view.php?id=35905> in regards to ISO compliance with case blocks (when under $mode iso).  Currently, a compiler error is raised if a case block does not have exhaustive coverage for the input type (it's a warning on other modes). According to ISO7185 <http://pascal-central.com/docs/iso7185.pdf>, page 55, section 6.8.3.5: "On execution of the case-statement the case-index shall be evaluated. That value shall then specify execution of the statement of the case-list-element closest-containing thecase-constant denoting that value. One of the case-constants shall be equal to the value of the case-index upon entry to the case-statement; otherwise, it shall be an error." Given it says "on execution", it implies this all occurs at run-time, especially as 'case-index' is usually a variable or otherwise non-deterministic at compile-time, hence the error should be a run-time error, not a compile-time error.  I think the issue is that FPC won't compile some well-known ISO Pascal code <https://bugs.freepascal.org/view.php?id=35859> because some of the case blocks don't exhaustively cover all inputs (which itself might be a sign of bad programming, but could be justified if said values are determined to be logically impossible, in which case the else blocks should contain assertions or internal errors). Just interpreting the standard, I think that the error should be run-time, not compile-time (although definitely keep the warning).  That's just my take on it though.  If it is to be changed, it should be simple enough by configuring the 'elselabel' field to point to an error-raising routine rather than 'endlabel' (which occurs if there's no else block). Gareth aka. Kit <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> Virus-free. www.avast.com <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Regards, Martok Ceterum censeo b32079 esse sanandam.

Reply by email

thaddy
to Martok
Indeed the wording between 7185 and 10206 has changed little, but
important: dynamic. Therefor note I still think the patch is acceptable.
I studied some more on the subject and here I will try and explain what
the actual behavior needs to be when one want to interpret the ISO 7185
case very strict.
In that case we need a different patch to solve the issue that is more
complex: suppose ISO 7185 is interpreted very strict, then one should
read it as I illustrate with three examples.
The current ISO implementation has bugs anyway. If one has to keep the
*compile time* error a patch needs to solve this type of code *without*
an error or warning:
--------------------------------------------
program testisocase1(infile,outfile);
// If compile time for iso 7185 errors are correct:
// this code currently throws a compile-time error
// and that's a bug.
// It should give no error at all and no warning at all
// After the patch there is still a- spurious - warning (small bug in
extendedpascal!)
type
   operator = 3..5;
var
   x:integer;
   o:operator = 4;
begin
   x:=1;
   case o of
     3 : x := x;// all
     4 : x := x;// possible
     5 : x := x;// cases
   end;
end.
-------------------------------------------

And if ISO 7185 is interpreted to throw a compile time error, this code should throw a compile time error:

-------------------------------------------
program testisocase2(infile,outfile);
// If compile time for iso 7185 errors are correct:
// This code should throw a compile time error with the current
interpretation
// and it does.
// But after my after the patch it throws a run-time error
// not a compile time error.
type
   operator = 3..5;
var
   x:integer;
   o:operator = 4; // here it is an invalid value
begin
   x:=1;
   case o of
     3 : x := x;
     // 4 : x := x;// this label removed!
     5 : x := x;
   end;
end.
-----------------------------------------

And this code should issue just a warning:

-----------------------------------------
program testisocase3(infile,outfile);
// If compile time for iso 7185 errors are correct:
// This code should issue a warning and not a compile time error
// since the labels are in the ordinal range.
// My patch handles this case correct.
type
   operator = 3..5;
var
   x:integer;
   o:operator = 3;
begin
   x:=1;
   case o of
     3 : x := x;// valid
     5 : x := x;// labels
   end;
end.
---------------------------------------
Summary:
if current interpretation is correct, then to the best of my knowledge:
case 1 is a big bug:throws compile error on good code. Needs to be fixed
anyway.
case 2 handles correct throws compile error on value without label
case 3 is a bug throws compile error, but should issue a warning, not an
error

if ISO 10206 behavior is acceptable (which I think it is!): case 1 handles correct, but issues a spurious warning case 2 issues a run-time error
case 3 handles correct and issues a correct warning

The above is the exact behavior as in extendedpascal. Note that here this code proves that that code is also not fully correct because of the spurious warning.

Martok wrote 17 lines
If you want something a bit more clear, try ISO/IEC 10206 (Extended Pascal). They split up errors and dynamic violations, which helps make the point clearer. The patch to switch from option a1) to a2) would be straightforward, fix 32079 and insert a default otherwise clause that raises a RunError in -Miso. But the question is again, does Freepascal actually aim to be compliant with anything, or just have a compatible syntax and do its own thing from there? Best, Sebastian

Reply by email

Marco Borsari
to Martok: If you want something a bit more clear, try ISO/IEC 10206 (Extended Pascal). They split…
Show quoted text 8 lines
Of course, if you wanted a run-time error you would need to insert a run-time check, and 'some people' seemed to be hell-bent on saving these 2 cycles at any cost. The patch to switch from option a1) to a2) would be straightforward, fix 32079 and insert a default otherwise clause that raises a RunError in -Miso. But the question is again, does Freepascal actually aim to be compliant with anything, or just have a compatible syntax and do its own thing from there?

It seems to me that the problem of a lack of correspondence in a case statement list should be of the same level of attention of the index limits of an array, except there is no memory corruption risk. The solution could be to insert a run time check in presence of the switch {$R+}, if the latter is allowed in iso mode.

Greetings, Marco Borsari

Simplex sigillum veri

Reply by email

thaddy
to Marco Borsari
Marco Borsari wrote 24 lines
On Wed, 31 Jul 2019 01:26:23 +0200 Martok wrote: > Of course, if you wanted a run-time error you would need to insert a > run-time > check, and 'some people' seemed to be hell-bent on saving these 2 > cycles at any > cost. > > The patch to switch from option a1) to a2) would be straightforward, > fix 32079 > and insert a default otherwise clause that raises a RunError in -Miso. > But the > question is again, does Freepascal actually aim to be compliant with > anything, > or just have a compatible syntax and do its own thing from there? It seems to me that the problem of a lack of correspondence in a case statement list should be of the same level of attention of the index limits of an array, except there is no memory corruption risk. The solution could be to insert a run time check in presence of the switch {$R+}, if the latter is allowed in iso mode. Greetings, Marco Borsari

No, that is not allowed in the context of the standards, but the compiler solves that already earlier in the code path and if the code is compiled with {$rangechecks on} an out of bounds will be detected. What needs to be detected if all *used* labels are within the confines of the used ordinal, but a selector without label should throw an error. In the case of my patch it behaves like extended pascal mode and throws a run-time error in that case. That is debatable in some cases, because if the selector has no label and the compiler can resolve that at compile time it should in my opinion and how I read ISO 10206 throw a compile-time error. See my remarks and test code.
Maybe you can evaluate those conclusions I made.

Reply by email

Marco Borsari
to thaddy

Il 31/07/2019 08:37, thaddy ha scritto:

Show quoted text 11 lines
On 2019-07-31 08:26, Marco Borsari via fpc-devel wrote: What needs to be detected if all *used* labels are within the confines of the used ordinal, but a selector without label should throw an error. In the case of my patch it behaves like extended pascal mode and throws a run-time error in that case. That is debatable in some cases, because if the selector has no label and the compiler can resolve that at compile time it should in my opinion and how I read ISO 10206 throw a compile-time error. See my remarks and test code. Maybe you can evaluate those conclusions I made.

I read your code examples and I have to admit I was a little bit confused about the actual discussion: I was concerned only for the situation in which the value of variable does not match the case statement list, irrespectively of the ordinal type of the variable. For the latter I have no idea about what should be desiderable to do nor knowledge about standards.

Show quoted text 6 lines
I just compiled pascal-s (Moore's iso version, because that's the relevant one) but did not run it yet with my patch. It fails at run-time or compile-time? It is an interpreter/p-code system, so has a greater level of freedom. Note iso7158 is based on Wirth's but Wirth's version is not iso compliant.

For the situation I intended before, it raises an error when it executes the object code, please consider this code fragment of the procedure interpret:

12: begin (* switch *) h1 := s[t].i; t := t-1;
        h2 := ir.y; h3 := 0;
        repeat if code[h2].f  13 then
            begin h3 := 1; ps := caschk
            end else
          if code[h2].y = h1 then
            begin h3 := 1; pc := code[h2+1].y
            end else
          h2 := h2 + 2
        until h3  0
      end;

ps is set to caschk when all labels are been processed without a match and the processor reaches code 13, i.e. the end of case. I hope to be more near to the point this time,
Marco

Reply by email