소스 검색

* fixed range/overflow checking for succ/pred (mantis #16770)

git-svn-id: trunk@15474 -
Jonas Maebe 15 년 전
부모
커밋
04a63ea278
4개의 변경된 파일68개의 추가작업 그리고 2개의 파일을 삭제
  1. 1 0
      .gitattributes
  2. 0 2
      compiler/ncginl.pas
  3. 44 0
      compiler/ninl.pas
  4. 23 0
      tests/webtbs/tw16770.pp

+ 1 - 0
.gitattributes

@@ -10508,6 +10508,7 @@ tests/webtbs/tw1658.pp svneol=native#text/plain
 tests/webtbs/tw16668.pp svneol=native#text/plain
 tests/webtbs/tw16700.pp svneol=native#text/plain
 tests/webtbs/tw1677.pp svneol=native#text/plain
+tests/webtbs/tw16770.pp svneol=native#text/plain
 tests/webtbs/tw1681.pp svneol=native#text/plain
 tests/webtbs/tw1696.pp svneol=native#text/plain
 tests/webtbs/tw1699.pp svneol=native#text/plain

+ 0 - 2
compiler/ncginl.pas

@@ -394,8 +394,6 @@ implementation
         else
 {$endif not cpu64bitalu}
           cg.a_op_const_reg(current_asmdata.CurrAsmList,cgop,location.size,1,location.register);
-
-        cg.g_rangecheck(current_asmdata.CurrAsmList,location,resultdef,resultdef);
       end;
 
 

+ 44 - 0
compiler/ninl.pas

@@ -2661,6 +2661,50 @@ implementation
           in_succ_x:
             begin
               expectloc:=LOC_REGISTER;
+              { in case of range/overflow checking, use a regular addnode
+                because it's too complex to handle correctly otherwise }
+              if ([cs_check_overflow,cs_check_range]*current_settings.localswitches)<>[] then
+                begin
+                  { create constant 1 }
+                  hp:=cordconstnode.create(1,left.resultdef,false);
+                  typecheckpass(hp);
+                  if not is_integer(hp.resultdef) then
+                    inserttypeconv_internal(hp,sinttype);
+
+                  { avoid type errors from the addn/subn }
+                  if not is_integer(left.resultdef) then
+                    inserttypeconv_internal(left,sinttype);
+
+                  { addition/substraction depending on succ/pred }
+                  if inlinenumber=in_succ_x then
+                    hp:=caddnode.create(addn,left,hp)
+                  else
+                    hp:=caddnode.create(subn,left,hp);
+                  { assign result of addition }
+                  if not(is_integer(resultdef)) then
+                    inserttypeconv(hp,torddef.create(
+{$ifdef cpu64bitaddr}
+                      s64bit,
+{$else cpu64bitaddr}
+                      s32bit,
+{$endif cpu64bitaddr}
+                      get_min_value(resultdef),
+                      get_max_value(resultdef)))
+                  else
+                    inserttypeconv(hp,resultdef);
+
+                  { avoid any possible errors/warnings }
+                  inserttypeconv_internal(hp,resultdef);
+
+                  { firstpass it }
+                  firstpass(hp);
+
+                  { left is reused }
+                  left:=nil;
+
+                  { return new node }
+                  result:=hp;
+                end;
             end;
 
           in_setlength_x,

+ 23 - 0
tests/webtbs/tw16770.pp

@@ -0,0 +1,23 @@
+{ %result=201 }
+
+{$mode delphi}
+{$r+}
+procedure Test;
+var
+  Count: Word;
+  I: Integer;
+
+begin
+  Count := 0;
+
+  for I := 0 to Pred(Count) do
+    begin
+      WriteLn(I);
+      break;
+    end;
+end;
+
+begin
+  test;
+end.
+