|
@@ -0,0 +1,112 @@
|
|
|
+Program fpcbugcheck;
|
|
|
+
|
|
|
+{$mode macpas} { for | }
|
|
|
+
|
|
|
+Var
|
|
|
+ FrobCounter : Integer;
|
|
|
+
|
|
|
+const
|
|
|
+ ok: boolean = true;
|
|
|
+
|
|
|
+Function Frob : Boolean;
|
|
|
+begin
|
|
|
+ Inc(FrobCounter);
|
|
|
+ Frob := False;
|
|
|
+end;
|
|
|
+
|
|
|
+{
|
|
|
+ This program tests whether "Frob or Frob" is contracted to a single
|
|
|
+ "Frob" call, in different contexts:
|
|
|
+ - without shortcut evaluation (no contraction allowed)
|
|
|
+ - with shortcut evaluation enabled
|
|
|
+ - using the MacPas "|" instead of "or"
|
|
|
+ It prints the number of Frob calls for each variant.
|
|
|
+}
|
|
|
+
|
|
|
+{
|
|
|
+ The second test this program does is related to the first one,
|
|
|
+ it exercises a bug in fpc deeming all compares with string constants
|
|
|
+ to be equal at the stage of compilation the elision of duplicate expression
|
|
|
+ in bools is performed.
|
|
|
+
|
|
|
+ This bug has been active since the introduction of the boolean shortcut
|
|
|
+ optimization (r14714), but as that optimization only applies to the
|
|
|
+ explicit shortcut form (in form of the MacPas operators), that bug
|
|
|
+ didn't show.
|
|
|
+}
|
|
|
+
|
|
|
+{$B+}
|
|
|
+Procedure CountFrobsBoolFull;
|
|
|
+begin
|
|
|
+ FrobCounter := 0;
|
|
|
+ if Frob or Frob then
|
|
|
+ begin
|
|
|
+ WriteLn('Complete: Huh');
|
|
|
+ ok:=false;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ WriteLn('Complete: Frobbed ', FrobCounter, ' times');
|
|
|
+ if FrobCounter<>2 then
|
|
|
+ ok:=false;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+{$B-}
|
|
|
+Procedure CountFrobsBoolShort;
|
|
|
+begin
|
|
|
+ FrobCounter := 0;
|
|
|
+ if Frob or Frob then
|
|
|
+ begin
|
|
|
+ WriteLn('Short: Huh');
|
|
|
+ ok:=false;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ WriteLn('Short: Frobbed ', FrobCounter, ' times');
|
|
|
+ if FrobCounter<>2 then
|
|
|
+ ok:=false;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+Procedure CountFrobsMac;
|
|
|
+begin
|
|
|
+ FrobCounter := 0;
|
|
|
+ if Frob | Frob then
|
|
|
+ begin
|
|
|
+ WriteLn('Mac: Huh');
|
|
|
+ ok:=false;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ WriteLn('Mac: Frobbed ', FrobCounter, ' times');
|
|
|
+ if FrobCounter<>2 then
|
|
|
+ ok:=false;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+var
|
|
|
+ test: String;
|
|
|
+{$B-}
|
|
|
+begin
|
|
|
+ ok:=true;
|
|
|
+ { test conditions for application of boolean contraction }
|
|
|
+ CountFrobsBoolFull;
|
|
|
+ CountFrobsBoolShort;
|
|
|
+ CountFrobsMac;
|
|
|
+ { test for faulty boolean contraction }
|
|
|
+ test:='b';
|
|
|
+ if (test='a') | (test='b') then
|
|
|
+ test := 'OK'
|
|
|
+ else
|
|
|
+ ok:=false;
|
|
|
+ if test <> 'OK' then WriteLn('Mac: fpc failed!');
|
|
|
+ test:='b';
|
|
|
+ if (test='a') or (test='b') then
|
|
|
+ test := 'OK'
|
|
|
+ else
|
|
|
+ ok:=false;
|
|
|
+ if test <> 'OK' then WriteLn('Short: fpc failed!');
|
|
|
+ if not ok then
|
|
|
+ halt(1);
|
|
|
+end.
|