[fpc-devel] Const optimization is a serious bug

Martin fpc at mfriebe.de
Thu Jul 7 18:23:55 CEST 2011


On 07/07/2011 16:54, Alexander Klenin wrote:
> On Fri, Jul 8, 2011 at 02:35, Martin<fpc at mfriebe.de>  wrote:
>> On 07/07/2011 16:27, Alexander Klenin wrote:
>>> 1) That the code you posted would work quite correctly if "const
>>> string" is fixed,
>>>    including all the optimizations you are suggesting in the rest of
>>> your message.
>> No.
>>
>> As I said: IF the result of constant expressions like "s[a] = '<'" are
>> cached (in future) depending on optimization level, then it breaks.
> Well, maybe you should run the code and see for youself --
> I do not know how to explain this in even more detail.
> It will *only* break due to the current optimization bug.
> Remove the bug, and no breakage is possible,
> with or without caching you describe.
> Even now, if you ensure refcount>1, no breakage is possible.
>
>> The 2nd evaluation, of this expression without optimization returns a
>> different result from the 1st evaluation. (It may be that the example would
>> need updating, but there is code where this can happen, including if
>> ref-counting was done)
>>
>> So depending on the 2nd evaluation being done, or cached (future
>> optimization) the program flow differs.
> It only differs now due to the current optimization bug.
> Remove the bug, and the code will stop breaking.

Ok, so here I go, an example without "const" => that means the refcount 
is increased.

Yet it crashes.
But the crash is NOT the issue. After all this crash is not caused by 
"const". there is no const.
this crash is simply wrong code....

But it shows something else.
It shows that even with refcount in place, it is possible to modify (via 
a global var) the content of a local string.

Yes, I use pointers, but it does not matter how I managed to change the 
content of "s". All that matters is, that I broke the promise (assuming 
s was declared const")

But as soon as the content of s changes (and if s was declared const), 
the behaviour is simply unpredictable.

Because the second "s[2] = 'x'"  *could* be cached *or* evaluated; 
leading to a different execution path



-------

program Project1; {$mode objfpc}{$H+}
uses Classes;

var Foo: String;

procedure Ouch(a: pchar);
begin
   a[0] := 'x';
end;

procedure Test1(  (*const*)  s: String);
var x: TStringList;
begin
   if s[2] = 'x' then
     x := TStringList.Create;
   Ouch(@Foo[2]);
   if s[2] = 'x' then
     x.Add('lets hope');
end;

begin
   Foo := 'ab'+'12';
   Test1(Foo);
   readln;
end.




More information about the fpc-devel mailing list