View Issue Details

IDProjectCategoryView StatusLast Update
0034972FPCCompilerpublic2020-04-28 22:09
ReporterKai Burghardt Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Product Version3.0.4 
Summary0034972: usage of default-intrinsic does not trigger range checks
DescriptionWhen default(ordinalType) is used as the sole factor of an expression in an assignment, no range checks are triggered.
Steps To Reproduceprogram rangesWithoutDefault(input, output, stderr);
{$R+}
type
    r = -1..-1;
var
    i: r;
begin
    i := default(r);
    writeLn(i);
end.
Tagsrange checks
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files

Activities

Thaddy de Koning

2019-02-01 15:49

reporter   ~0113781

Last edited: 2019-02-01 15:51

View 2 revisions

default initializes the memory to zero's.
but indeed you example shows that it is not in range in your case.
So: confirmed, because the range check should execute.

Kai Burghardt

2020-04-27 22:01

reporter   ~0122474

Last edited: 2020-04-27 22:04

View 2 revisions

Suggestion: `default(T)` as sole factor in an expression yields a compile-time error if the range excludes `0` (zero).

Except: (In Extended Pascal:) For data types that have a defined default value.

Todo: While one can already specify an initialization value in a `var`-section, it is not associated with the data type. I suggest to implement Extended Pascal’s “initial-state-specifier”, cf. http://www.pascal-central.com/docs/iso10206.pdf (§ 6.6, PDF page 63), which links a “default” value _with_ a data _type_. The attached program should compile then.
rangesWithDefault.pas (234 bytes)   
program rangesWithDefault(input, output, stderr);
{$mode extendedPascal}
{$R+}
type
	negativeNumber = low(nativeInt)..-1 value -1;
var
	sadNumber: negativeNumber;
begin
	sadNumber := default(negativeNumber);
	writeLn(sadNumber);
end.
rangesWithDefault.pas (234 bytes)   

Serge Anvarov

2020-04-28 03:19

reporter   ~0122480

From https://www.freepascal.org/docs-html/rtl/system/default.html: "In essence, this is a block of memory that is zeroed out".
In Delphi (Default is not documented by last Delphi), there is no range check even when used in the declaration section.

Kai Burghardt

2020-04-28 10:47

reporter   ~0122488

Yes, you’re right, Serge. (As for now) `default` zeroes out a memory block. My point is though, zeroing out a memory block isn’t necessarily what I associate with the English word “default”. In assembly language it’s the `.zero` directive. “Zero” sounds like zeroing out, that’s plausible. And to be fair, in most cases `default` will assign `0` too, but it isn’t necessarily correct, hence this very bug report. Assigning zero to a range that doesn’t include zero is wrong and should not be possible (but apparently is). In Pascal’s spirit we should prevent the programmer from doing stupid things. Assigning an invalid value to a variable is one such “stupid thing”.

Jonas Maebe

2020-04-28 22:09

manager   ~0122512

A global variable will also be initialised with 0, even if that is not a valid value for that variable. The same goes for fields in a class. Default just is a way to be able to do this for any variable at any point. It is not guaranteed to be a valid value, but basically "make this variable uninitialised again".

The Extended Pascal functionality would definitely be useful, but that's different from the (Delphi-originated) Default() intrinsic.

Issue History

Date Modified Username Field Change
2019-01-30 06:37 Kai Burghardt New Issue
2019-01-30 06:37 Kai Burghardt Tag Attached: range checks
2019-02-01 15:49 Thaddy de Koning Note Added: 0113781
2019-02-01 15:51 Thaddy de Koning Note Edited: 0113781 View Revisions
2020-04-27 22:01 Kai Burghardt Note Added: 0122474
2020-04-27 22:01 Kai Burghardt File Added: rangesWithDefault.pas
2020-04-27 22:04 Kai Burghardt Note Edited: 0122474 View Revisions
2020-04-28 03:19 Serge Anvarov Note Added: 0122480
2020-04-28 10:47 Kai Burghardt Note Added: 0122488
2020-04-28 22:09 Jonas Maebe Note Added: 0122512