View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0016006||FPC||Compiler||public||2010-03-16 09:27||2020-07-14 21:30|
|Reporter||Adriaan van Os||Assigned To||Jonas Maebe|
|Platform||i386-apple-darwin||OS||Mac OS X|
|Summary||0016006: Dead code mistake|
|Description||The following program|
range = 1..96;
r:= range( i);
if r > 96
then writeln( 'r out of range')
else writeln( 'r = ', r)
gives a warning
testdeadcode.pas(11,10) Warning: unreachable code
and then produces the following wrong output
r = 100
|Tags||No tags attached.|
|Fixed in Revision|
|has duplicate||0024421||resolved||Jonas Maebe||Comparing variable with out of range value yields false without typecast|
|has duplicate||0029147||closed||Jonas Maebe||Don't get I/O error as expected by Array of [Enumrange]|
|has duplicate||0032079||resolved||Jonas Maebe||Jumptables for case..of may jump into invalid memory|
|has duplicate||0030423||resolved||Jonas Maebe||Range checks missing at runtime on type casts using sub ranges|
|has duplicate||0034100||resolved||Jonas Maebe||compiler doesn't generate range check code for boolean array|
|related to||0022179||closed||Florian||FPC trunk revision 21455 have major bug at Math units Max-procedure when using subranged type.|
|related to||0034140||closed||compiler removes code it wrongly believes to be unreachable|
|related to||0035753||resolved||Jonas Maebe||Delphi allows dereferencing a pointer to a [0..0] static array and accessing it with indices > 0, however 0035671 breaks this.|
|related to||0037342||resolved||Jonas Maebe||Regression: range check warning|
||If you explicitly disable the compiler's type checking, you can do anything. I think it is completely correct for the compiler to assume that variables of a particular type indeed only contain values that are valid for that type. Otherwise having a type system has little use.|
||The test program proves that the compile-time assumption that "variables of a particular type indeed only contain values that are valid for that type" is wrong. Worse, this assumption makes it impossible to check for the same at run-time.|
> The test program proves that the compile-time assumption that
> "variables of a particular type indeed only contain values that are
> valid for that type" is wrong.
Even in ADA you can perform unchecked type casts ( http://en.wikibooks.org/wiki/Ada_Programming/Subtypes#Unchecked_conversion ) and then the result is undefined "when the destination type can not hold the source value".
I stand by my opinion that if the program explicitly says that the compiler must not check a particular conversion, that the compiler is entitled to assume that it is valid (and hence that the result is also valid).
||I think the type cast is not the point. The important point is imo that r is declared 1..96 so the compiler can assume that r contains no other values. If it contains other values, the behaviour is implementation specific.|
I agree with Florian that the type cast is not the point. But I disagree with the compiler assumption that the value of of a variable is always in the declared range. That is very optimistic ....
There are many reasons why the runtime value of a variable can be outside its compile-time declared range. I mention: untyped pointers, blockmoves, typecasts, blockreads, calling external code, calling system software, variant parts of a case record, etcetera.
Only a language that forbids all those operations (and running on fault-tolerant hardware) can safely make the above assumption. And therefore a well-written program builds-in value checks at runtime. And therefore it doesn't like the compiler optimizing away those checks ....
The typecast actually is the whole point for the example program, see the Ada explanation: that expression means that any further operation on that value is undefined if the original value was out of range.
Optimising based on type inference is done in every single compiler for every single typed language I know of, regardless of the platform or hardware you run on (from Java to C to Ada, even though in all cases you can corrupt values via assembler code or due to running on buggy hardware, cosmic rays, and except for Java due to uninitialised values).
If you don't want the compiler to take into account particular type information, then you cannot give it any such information and must perform the corresponding checks manually.
||You can always write "if longint(r) > 96 then" if you want the compiler to ignore the type information in that statement as well.|
|2010-03-16 09:27||Adriaan van Os||New Issue|
|2010-03-16 12:13||Jonas Maebe||Status||new => resolved|
|2010-03-16 12:13||Jonas Maebe||Resolution||open => no change required|
|2010-03-16 12:13||Jonas Maebe||Assigned To||=> Jonas Maebe|
|2010-03-16 12:13||Jonas Maebe||Note Added: 0035634|
|2010-09-21 10:46||Adriaan van Os||Status||resolved => feedback|
|2010-09-21 10:46||Adriaan van Os||Resolution||no change required => reopened|
|2010-09-21 10:46||Adriaan van Os||Note Added: 0041258|
|2010-09-21 11:32||Jonas Maebe||Status||feedback => resolved|
|2010-09-21 11:32||Jonas Maebe||Resolution||reopened => no change required|
|2010-09-21 11:32||Jonas Maebe||Note Added: 0041259|
|2010-09-21 11:49||Jonas Maebe||Note Edited: 0041259|
|2010-09-21 17:04||Florian||Note Added: 0041264|
|2010-10-10 16:22||Adriaan van Os||Status||resolved => feedback|
|2010-10-10 16:22||Adriaan van Os||Resolution||no change required => reopened|
|2010-10-10 16:22||Adriaan van Os||Note Added: 0041688|
|2010-10-10 17:01||Jonas Maebe||Status||feedback => resolved|
|2010-10-10 17:01||Jonas Maebe||Resolution||reopened => won't fix|
|2010-10-10 17:01||Jonas Maebe||Note Added: 0041690|
|2010-10-10 17:04||Jonas Maebe||Note Added: 0041691|
|2012-06-03 11:40||Jonas Maebe||Relationship added||related to 0022179|
|2013-05-13 13:57||Jonas Maebe||Relationship added||has duplicate 0024421|
|2013-11-28 21:53||Jonas Maebe||Status||resolved => closed|
|2015-12-07 23:33||Jonas Maebe||Relationship added||has duplicate 0029147|
|2017-06-29 20:03||Jonas Maebe||Relationship added||has duplicate 0032079|
|2018-08-08 19:18||Jonas Maebe||Relationship added||has duplicate 0030423|
|2018-08-08 19:19||Jonas Maebe||Relationship added||has duplicate 0034100|
|2018-08-17 17:53||Jonas Maebe||Relationship added||related to 0034140|
|2019-06-22 21:52||Jonas Maebe||Relationship added||related to 0035753|
|2020-07-14 21:30||Jonas Maebe||Relationship added||related to 0037342|