I today realized that current trunk does not work anymore after Rev 50151, Lazarus starts and when I load a project I get a Range Check Error and after this I cannot open source files.
Is this a known issue?
Michael

Mailing lists / lazarus / 2015-10
21 messages · 3 people · –
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
I today realized that current trunk does not work anymore after Rev 50151, Lazarus starts and when I load a project I get a Range Check Error and after this I cannot open source files.
Is this a known issue?
Michael
What FPC version?
What options did you use to compile the IDE?
Mattias
Here's the info:
/usr/local/bin/fpc -i
Free Pascal Compiler version 2.6.4
Compiler Date : 2014/02/26
Compiler CPU Target: i386
---
LCL_PLATFORM=carbon
CPU_TARGET=i386
COMPILERSWITCH="--compiler=/usr/local/bin/fpc"
make clean all CPU_TARGET=$CPU_TARGET LCL_PLATFORM=$LCL_PLATFORM OPT="-k'-framework' -k'ApplicationServices'" || exit 1
Michael
Fixed.
Mattias
Mattias Gaertner wroteFixed.
How did you find it from the description? You are a wizard :) Sorry for introducing the bug in my code. But I know how it happened: it was introduced by CodeTools variable completion:
procedure TIDECommands.PostponeUpdateEvents;
begin
FDontExecuteUpdateEventsUntil := GetTickCount64 + 500;
end;if FDontExecuteUpdateEventsUntil is not declared and I complete it with Ctrl+Shift+C it creates an integer variable:
procedure TIDECommands.PostponeUpdateEvents;
var
FDontExecuteUpdateEventsUntil: Integer;
begin
FDontExecuteUpdateEventsUntil := GetTickCount64 + 500;
end;I then moved the FDontExecuteUpdateEventsUntil declaration to the private section without checking the actual type of it.
If you complete without the addition, the type is correct:
procedure TIDECommands.PostponeUpdateEvents;
var
FDontExecuteUpdateEventsUntil: QWord;
begin
FDontExecuteUpdateEventsUntil := GetTickCount64;
end;Should I report it in the bug tracker?
Ondrej
On 03.11.2015 17:08, Mattias Gaertner wrote: > Fixed. How did you find it from the description?
I didn't. I tested on OS X.
codetools use only a simple heuristic to calculate the type of a binary operator.
The function TFindDeclarationTool.CalculateBinaryOperator needs to be extended for Alias types (e.g. 'integer' instead of longint) and for ranges (e.g. if the operands do not fit into an integer).
Should I report it in the bug tracker?
Yes.
Mattias
Thank you for the fix, just tried it on fresh trunk, works!
Michael
On Tue, 3 Nov 2015 17:24:02 +0100 I didn't. I tested on OS X. codetools use only a simple…
Maybe you are talking about the same, but just to be sure: IMO using hard-coded alias types is not a good idea (theoretically the user can redefine them). Instead the type evaluation should go to the end type (e.g. from Integer to *longint*) and then the end types should be compared. The comparison can then be done with a hard-coded table (you need it only for the basic types, so it is OK and safe) and the type that wins, will be used as the result type (obviously the originally used alias).
E.g.:
procedure Test;
var
I: Integer;
S: SmallInt;
begin
Res := I + S;
end;Something like:
1.)
I = (Integer -> longint)
S = SmallInt
2.)
ResultBasicType = Compare(longint, SmallInt) -> longint -> I 3.)
ResultType = ResultBasicType -> I -> *Integer*
Reported:
http://mantis.freepascal.org/view.php?id=28953
Ondrej
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20151103/dd262436/attachment.html>
No, I meant that 'integer' is defined as
type integer = longint;
For the compiler 'integer' is just an alias for longint. But codetools should use the alias as much as possible instead of the underlying base type.
Maybe I should have used 'SizeInt' as an example. SizeInt can be longint or int64. When a function returns SizeInt codetools should declare the variable as SizeInt instead of the current base in order to help creating cross platform code.
That would fail with the following example:
var
i: SizeInt;
j: SmallInt;
begin
k:=i+j;
end;The result should be SizeInt, not Integer.
Of course there are some hard coded defaults in codetools. For example "i:=3" can be any integer type. In TP/Delphi/LCL applications "integer" is used so often it is a good default.
Same for "String".
But what type should "i:=3.0" create? Single, Double, Extended, glFloat?
It would be nice if codetools could guess the "usual" type from the surrounding code or if it can be set via an IDE/project/package option.
Mattias
No, the result will be SizeInt, because (SizeInt -> LongInt) wins over SmallInt and the result thus will be SizeInt (as the original type alias of /*i*/) and not Integer.
A problem could be with such code:
var
i: SizeInt;
j: Integer;
begin
k:=i+j;
end;Because obviously on 32bit SizeInt=longint and Integer=longint, so there won't be a deterministic way which type wins.
Ondrej
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20151103/70cfc62a/attachment.html>
But this is a similar issue like the one from this report (check all different IFDEFs for the "biggest" type)...
http://bugs.freepascal.org/view.php?id=28317
So probably not to be solved.
Otherwise IMO the comparison of base types and using the aliases from the definitions is the cleanest way to do it.
What if I use my own aliases that won't be supported by CodeTools or if I redefine the usual aliases (I know, bad idea, but still)? The "compare base types - use aliases" approach will still work.
Ondrej
Probably the best approach is:
1.) Compare base types with the table.
1a.) If they are equal, goto 2.
1b.) If they differ, set winner according to table and go to 3.
2.) Compare aliases with the table, set winner.
3.) Use the original alias of the winner as result.
About the table:
We need one table for integer and one for floating-point types. The integer table could look like ['int64', 'sizeint', 'integer', 'smallint'] (but with all integer types and probably a good idea to allow the user to modify and enhance it - e.g. a simple TStringList). The winner is the one closest to the left (top - smallest index).
Ondrej
No, the result will be SizeInt, because (SizeInt -> LongInt) wins over SmallInt and the…
Good.
Left side wins.
It can't be perfect, but it should be deterministic.
Mattias
Probably the best approach is: 1.) Compare base types with the table. 1a.) If they are…
Many libs has such types. I have not counted, but I guess the FPC sources has hundreds of them. Probably some of them conflict each other. So something better than a TStringList should be used.
Mattias
On Tue, 3 Nov 2015 20:34:30 +0100 Good. Left side wins. It can't be perfect, but it…
Could you tell which one to use?
Ondrej
On Tue, 3 Nov 2015 20:34:30 +0100 Good. Left side wins. It can't be perfect, but it…
Fixed in r50217.
SizeInt always wins - both if it is on left side or right side because it has a higher rank than Integer. So it is now completely deterministic. (Under "not deterministic" I ment that "k:=i+j" and "k:=j+i" return different types, which is the case of "left side wins".)
Ok, I used just a simple "array of string". It's not the fastest/best for adding items one-by-one but there are not so many types, so who cares... It can be easily replaced if you don't like it.
+ I may have not added all predefined types in:
function BooleanTypesOrderList: TTypeAliasOrderList;
function IntegerTypesOrderList: TTypeAliasOrderList;
function RealTypesOrderList: TTypeAliasOrderList;
function StringTypesOrderList: TTypeAliasOrderList;you are welcome to extend them.
Ondrej
On Tue, 3 Nov 2015 19:37:04 +0100 No, I meant that 'integer' is defined as type integer =…
Mattias Gaertner wroteOf course there are some hard coded defaults in codetools. For example "i:=3" can be any integer type.
It would be nice if integer constants were able to resolve their type:
3 -> ShortInt
180 -> SmallInt
etc etc.
This would be good for:
var
b: Byte;
begin
i := b + 500;
end;this code creates "i: Byte;" in r50230.
I still think it is better than the behavior before r50230 that created "i: Integer;" for:
var
b: Byte;
begin
i := b + 1;
end;Because adding a constant out of the bounds of one operand is much less common than within its bounds (IMO).
But what type should "i:=3.0" create? Single, Double, Extended, glFloat?
Yes, whatever: single, double, extended, glFloat - maybe create an IDE option for default integer/float/string/boolean types? The user then can decide what precision he wants to use by default. Do you think it is possible?
The integer predefined setting should be preferred to the resolved type in case there is no well-defined variable. E.g.:
i := 10 + 5;
Should create the user-defined default integer type ("i: integer" by default) and not "i: Byte".
Ondrej
Could you tell which one to use? Ondrej
For example a sorted TStringList with the 'Objects' as the position.
Mattias
Fixed in r50217. SizeInt always wins - both if it is on left side or right side because…
I meant in doubt 'Left side wins'.
For example 'somethingA+somethingB' and both types are longint it should return somethingA.
Since codetools do not yet support operator overloading it can't resolve correctly 'someMatrix'+'someVector'. It should deterministically return left side, because the important type usually is at the beginning.
Ok, I used just a simple "array of string". It's not the fastest/best for adding items one-by-one but there are not so many types, so who cares... It can be easily replaced if you don't like it.
The list is seldom edited so editing does not need much speed. Fast search is important. As long as there are only 20 types the structure is irrelevant. But when we extend the list for all types of the FPC packages the list gets big.
Thanks.
Mattias
It would be nice if integer constants were able to resolve their type: 3 -> ShortInt 180…
The 500 is for codetools an xtConstOrdInteger.
It is FindExprTypeAsString that returns 'Integer' for xtConstOrdInteger.
Fine with me.
Yes, why not?
Yes.
Mattias
On Wed, 4 Nov 2015 08:23:26 +0100 I meant in doubt 'Left side wins'. For example…
Yes, I'll change the array to TAvlTree, indexed by type/alias name and an order/position number. Seems to be a little bit cleaner than casting TObject to a number.
Mattias Gaertner wroteThe 500 is for codetools an xtConstOrdInteger. It is FindExprTypeAsString that returns 'Integer' for xtConstOrdInteger.
We needed "xtConstOrdSmallInt", "xtConstOrdShortInt", "xtConstOrdInteger/xtConstOrdLongInt" and "xtConstOrdInt64" for it (e.g. 500 would return xtConstOrdShortInt). It looks like an overkill for me, so let's keep the limitation for now with the knowledge that if the need arises, we could extend it.
The question was a little bit confusing :) Yes, adding IDE options with default types for Integer+Real+String constants looks very useful to me. Boolean isn't needed, IMO, but maybe it should be added as well for the sake of completeness.
Ondrej