Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Compiler/Delphi/Code Generation/Optimization    [ Add a report in this area ]  
Report #:  119197   Status: Closed
subtraction of sets changes its params
Project:  Delphi Build #:  18.0.4905.60485
Version:    18.1 Submitted By:   René Hoffmann
Report Type:  Crash / Data loss / Total failure Date Reported:  9/23/2013 8:01:54 AM
Severity:    Critical / Show Stopper Last Updated: 12/10/2013 6:29:13 PM
Platform:    All platforms Internal Tracking #:   43829
Resolution: Fixed (Resolution Comments) Resolved in Build: : XE5 Update2
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 10
Description
I noticed some very strange behaviour of optimized code when subtracting two sets.

set M1 contains [A,B] // M1 is a global variable
set M2 contains [B]   // M2 is a local variable

This should be done:
M1 := M1 ?M2;

When optimization is activated, M1 and M2 have the following values after the subtraction:

M1 = [A]
M2 = [A, C] // value of M2 has been negated!

When optimization is inactive, M1 and M2 have the correct values:

M1 = [A]
M2 = [B]


The attached project provides a good example for this behavior.
Steps to Reproduce:
Compile and run this code:
-----------
program SetDemo;
{$APPTYPE CONSOLE}
{$R *.res}
uses
  System.SysUtils;

type
  TMyEnum = (meOne, meTwo, meThree);
  TMySet = set of TMyEnum;

var
  GlobalSet: TMySet;

procedure DoAction(const ASet: TMySet);
var
  LocalSet: TMySet;
begin
  LocalSet := GlobalSet * ASet;
  GlobalSet := GlobalSet - LocalSet; // !!! LocalSet will be negated here, when optimization is on

  // !!! the following if-statements shouldn't be true, if the statement above worked properly
  if [meOne, meThree] * LocalSet <> [] then
    Writeln('[meOne, meThree] * LocalSet <> []');
  if meThree in LocalSet then
    WriteLn('meThree in LocalSet');
end;

begin
  try
    GlobalSet := [meOne, meTwo];
    DoAction([meTwo]);

    Readln; // keep the console open
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
-----------
Workarounds
Deactivate optimization, which is not a proper workaround for me.
Attachment
Set-Subtraktion Demo.zip
Comments

Tomohiro Takahashi at 9/23/2013 5:05:11 PM -
I deleted QC#119193, 119194,  119195, 119196 as Sysop. Please do not post same reports.

René Hoffmann at 9/24/2013 1:50:19 AM -
Please excuse me, the multi-post wasn't intentional. When trying to attach a zip-file I got the report form (it was empty) with an error message. So I used the 'go back' button of my browser and tried it a few more times with the same result. In the end I did it without attachment and it worked.

Tomohiro Takahashi at 9/23/2013 5:10:10 PM -
> When optimization is inactive ...
> ...
> The attached project provides ...
Could you please attach sample project(as a .zip file) to this report?
Note:
  Please use Windows Native QC Client. The standalone client comes with Delphi.

and, is this a regression in Delphi XE4? What about previous versions of Delphi?

René Hoffmann at 9/24/2013 1:32:47 AM -
I am sorry, but it seems I can't attach a file to this report. Neither does it work with the QCClient.

Instead, I uploaded the zipped project to my GoogleDrive. You can download it here: https://docs.google.com/file/d/0B3sxto_ED19fcTR1U1RNSDBneGs/edit?usp=sharing

Anyway it contains just the code I wrote in the report itself.

In Delphi 2007 the operation works fine.

Tomohiro Takahashi at 9/24/2013 8:17:42 PM -
I attached the .zip file to this report instead of you.
Thanks.

René Hoffmann at 10/4/2013 6:26:52 AM -
I'm very pleased to see that this issue got fixed so fast. We just upgraded our application from Delphi 2007 to Delphi XE4 and optimization is very important for the applications performance. Without it, some parts of our application could be up to 30 percent slower.
So I wonder when the fix will be delivered?

Server Response from: ETNACODE01