Prechádzať zdrojové kódy

* 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 rokov pred
rodič
commit
4da6039f40

+ 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/tw3351.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/tw3360.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)
           function pass_1: tnode; override;
           procedure pass_generate_code;override;
+          class function emptydynstrnil: boolean; override;
        end;
 
        tjvmsetconsttype = (
@@ -246,6 +247,11 @@ implementation
         thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,resultdef,location.register);
       end;
 
+    class function tjvmstringconstnode.emptydynstrnil: boolean;
+      begin
+        result:=false;
+      end;
+
 
     {*****************************************************************************
                                TJVMSETCONSTNODE

+ 11 - 1
compiler/ncnv.pas

@@ -2924,7 +2924,17 @@ implementation
                 resultdef:=left.resultdef;
                 left:=nil;
                 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 :
             begin

+ 8 - 0
compiler/ncon.pas

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