Ver Fonte

* do not swap left/right code generation for assignment nodes if
conditional expressions are involved, resolves #38129
(cherry picked from commit cc64d9eb4e036d8185c75393c21968cdbbb73e87)

# Conflicts:
# .gitattributes

florian há 4 anos atrás
pai
commit
1127761f49
2 ficheiros alterados com 26 adições e 2 exclusões
  1. 5 2
      compiler/ncgld.pas
  2. 21 0
      tests/webtbs/tw38129.pp

+ 5 - 2
compiler/ncgld.pas

@@ -719,10 +719,13 @@ implementation
               empty value is assigned
 
            But not when the result is in the flags, then
-          loading the left node afterwards can destroy the flags.
+           loading the left node afterwards can destroy the flags.
+
+           Neither if right contains conditional nodes: this might cause problems with
+           temp. nodes with init code used by CSE, see e.g. #38129
         }
         if not(right.expectloc in [LOC_FLAGS,LOC_JUMP]) and
-            (node_complexity(right)>node_complexity(left)) then
+            (node_complexity(right)>node_complexity(left)) and not(has_conditional_nodes(right)) then
          begin
            secondpass(right);
            if codegenerror then

+ 21 - 0
tests/webtbs/tw38129.pp

@@ -0,0 +1,21 @@
+{ %opt=-O3 }
+{$mode objfpc}
+{$H+}
+function Bar(const progress: single; divs: uint32): string;
+const
+    BarSym: array[boolean] of char = ('.', '#');
+var
+    i: int32;
+begin
+    SetLength(result, divs);
+    for i := 0 to int32(divs) - 1 do
+        pChar(result)[i] := BarSym[(progress >= (0.75 + i) / divs) or (i = int32(divs) - 1) and (progress >= 1)];
+end;
+
+var
+    s: string;
+
+begin
+  if Bar(0.7, 10)<>'#######...' then
+    halt(1);
+end.