Pārlūkot izejas kodu

* simplify empty-dynamic-string-to-pointer (non-p(wide)char) type conversions
so that they cannot result in "cmp const, const" at the assembler level
(mantis #33548)

git-svn-id: trunk@38662 -

Jonas Maebe 7 gadi atpakaļ
vecāks
revīzija
4da6039f40
5 mainītis faili ar 66 papildinājumiem un 1 dzēšanām
  1. 1 0
      .gitattributes
  2. 6 0
      compiler/jvm/njvmcon.pas
  3. 11 1
      compiler/ncnv.pas
  4. 8 0
      compiler/ncon.pas
  5. 40 0
      tests/webtbs/tw33548.pp

+ 1 - 0
.gitattributes

@@ -16097,6 +16097,7 @@ tests/webtbs/tw3348.pp svneol=native#text/plain
 tests/webtbs/tw3349.pp svneol=native#text/plain
 tests/webtbs/tw3349.pp svneol=native#text/plain
 tests/webtbs/tw3351.pp svneol=native#text/plain
 tests/webtbs/tw3351.pp svneol=native#text/plain
 tests/webtbs/tw3353.pp svneol=native#text/plain
 tests/webtbs/tw3353.pp svneol=native#text/plain
+tests/webtbs/tw33548.pp svneol=native#text/plain
 tests/webtbs/tw3356.pp svneol=native#text/plain
 tests/webtbs/tw3356.pp svneol=native#text/plain
 tests/webtbs/tw3360.pp svneol=native#text/plain
 tests/webtbs/tw3360.pp svneol=native#text/plain
 tests/webtbs/tw3364.pp svneol=native#text/plain
 tests/webtbs/tw3364.pp svneol=native#text/plain

+ 6 - 0
compiler/jvm/njvmcon.pas

@@ -48,6 +48,7 @@ interface
        tjvmstringconstnode = class(tstringconstnode)
        tjvmstringconstnode = class(tstringconstnode)
           function pass_1: tnode; override;
           function pass_1: tnode; override;
           procedure pass_generate_code;override;
           procedure pass_generate_code;override;
+          class function emptydynstrnil: boolean; override;
        end;
        end;
 
 
        tjvmsetconsttype = (
        tjvmsetconsttype = (
@@ -246,6 +247,11 @@ implementation
         thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,resultdef,location.register);
         thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,resultdef,location.register);
       end;
       end;
 
 
+    class function tjvmstringconstnode.emptydynstrnil: boolean;
+      begin
+        result:=false;
+      end;
+
 
 
     {*****************************************************************************
     {*****************************************************************************
                                TJVMSETCONSTNODE
                                TJVMSETCONSTNODE

+ 11 - 1
compiler/ncnv.pas

@@ -2924,7 +2924,17 @@ implementation
                 resultdef:=left.resultdef;
                 resultdef:=left.resultdef;
                 left:=nil;
                 left:=nil;
                 exit;
                 exit;
-              end;
+              end
+            else if
+              (convtype<>tc_cstring_2_pchar)  and
+              is_dynamicstring(left.resultdef) and
+              (tstringconstnode(left).len=0) and
+              (resultdef.typ=pointerdef) and
+              cstringconstnode.emptydynstrnil then
+            begin
+              result:=cnilnode.create;
+              exit;
+            end;
 
 
           realconstn :
           realconstn :
             begin
             begin

+ 8 - 0
compiler/ncon.pas

@@ -121,6 +121,9 @@ interface
           function docompare(p: tnode) : boolean; override;
           function docompare(p: tnode) : boolean; override;
           procedure changestringtype(def:tdef);
           procedure changestringtype(def:tdef);
           function fullcompare(p: tstringconstnode): longint;
           function fullcompare(p: tstringconstnode): longint;
+          { returns whether this platform uses the nil pointer to represent
+            empty dynamic strings }
+          class function emptydynstrnil: boolean; virtual;
        end;
        end;
        tstringconstnodeclass = class of tstringconstnode;
        tstringconstnodeclass = class of tstringconstnode;
 
 
@@ -1028,6 +1031,11 @@ implementation
           result:=compareansistrings(value_str,p.value_str,len,p.len);
           result:=compareansistrings(value_str,p.value_str,len,p.len);
       end;
       end;
 
 
+    class function tstringconstnode.emptydynstrnil: boolean;
+      begin
+        result:=true;
+      end;
+
 {*****************************************************************************
 {*****************************************************************************
                              TSETCONSTNODE
                              TSETCONSTNODE
 *****************************************************************************}
 *****************************************************************************}

+ 40 - 0
tests/webtbs/tw33548.pp

@@ -0,0 +1,40 @@
+program app_test_core;
+
+{$inline on}
+
+{$IFDEF MSWINDOWS}
+  {$APPTYPE CONSOLE}
+{$ELSE !MSWINDOWS}
+  {$H+}
+{$ENDIF !MSWINDOWS}
+
+uses
+  Classes, SysUtils;
+
+const
+  EMPTY_STRING: Char = #0;
+
+  function StrToPChar(const Value: string): PChar; inline;
+  begin
+    if Pointer(Value) <> nil then
+      StrToPChar := Pointer(Value)
+    else
+      StrToPChar := @EMPTY_STRING;
+  end;
+
+  procedure LogTextA(const TextPtr: PChar; const TextLen: Integer);
+  var
+    T: string;
+  begin
+    SetString(T, TextPtr, TextLen);
+    writeln('"', T, '"');
+  end;
+
+  procedure LogTextB(const Text: string); inline;
+  begin
+    LogTextA(StrToPChar(Text), Length(Text));
+  end;
+
+begin
+  LogTextB('');
+end.