View Issue Details

IDProjectCategoryView StatusLast Update
0034526FPCCompilerpublic2019-04-06 16:30
ReporterRyan JosephAssigned ToSven Barth 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version3.3.1Product Build 
Target VersionFixed in Version3.3.1 
Summary0034526: := class operator bug with implicit arrays
Descriptionclass operator := on records gives and error when assigning implicit arrays.
Steps To Reproduce{$mode objfpc}
{$modeswitch advancedrecords}

program general;

type
    TIntArray = array of integer;
    TMyRec = record
        a: TIntArray;
        class operator := (right:TIntArray):TMyRec;
    end;

class operator TMyRec.:= (right:TIntArray):TMyRec;
begin
    result.a := right;
end;

var
    r: TMyRec;
begin
    r := [1, 2, 3]; // Incompatible types: got "Set Of Byte" expected "TMyRec"
end.
Additional InformationA similar bug was reported and fixed but it only applies to the + operator.

https://bugs.freepascal.org/view.php?id=34021
TagsNo tags attached.
Fixed in Revision41844
FPCOldBugId
FPCTarget
Attached Files
  • patch.diff (1,165 bytes)
    From 59392503ef3e835a3a7d874d40d02a17af6bb559 Mon Sep 17 00:00:00 2001
    From: Ryan Joseph <genericptr@gmail.com>
    Date: Sat, 23 Mar 2019 13:01:36 -0400
    Subject: [PATCH] array constructor assignment overload bug fix
    
    ---
     compiler/ncnv.pas | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas
    index 31135872da..63f2045cbd 100644
    --- a/compiler/ncnv.pas
    +++ b/compiler/ncnv.pas
    @@ -2388,10 +2388,10 @@ implementation
                not(resultdef.typ in [procvardef,recorddef,setdef]) then
               maybe_call_procvar(left,true);
     
    -        { convert array constructors to sets, because there is no conversion
    -          possible for array constructors }
    +        { convert array constructors to sets unless there is an assignment operator }
             if (resultdef.typ<>arraydef) and
    -           is_array_constructor(left.resultdef) then
    +           is_array_constructor(left.resultdef) and 
    +           (search_assignment_operator(left.resultdef,resultdef,nf_explicit in flags)=nil) then
               begin
                 arrayconstructor_to_set(left);
                 typecheckpass(left);
    -- 
    2.17.2 (Apple Git-113)
    
    
    patch.diff (1,165 bytes)

Relationships

has duplicate 0035061 resolvedSven Barth Operator overloads see literal arrays as "Set of ..." 

Activities

Ryan Joseph

2019-03-23 18:03

reporter  

patch.diff (1,165 bytes)
From 59392503ef3e835a3a7d874d40d02a17af6bb559 Mon Sep 17 00:00:00 2001
From: Ryan Joseph <genericptr@gmail.com>
Date: Sat, 23 Mar 2019 13:01:36 -0400
Subject: [PATCH] array constructor assignment overload bug fix

---
 compiler/ncnv.pas | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas
index 31135872da..63f2045cbd 100644
--- a/compiler/ncnv.pas
+++ b/compiler/ncnv.pas
@@ -2388,10 +2388,10 @@ implementation
            not(resultdef.typ in [procvardef,recorddef,setdef]) then
           maybe_call_procvar(left,true);
 
-        { convert array constructors to sets, because there is no conversion
-          possible for array constructors }
+        { convert array constructors to sets unless there is an assignment operator }
         if (resultdef.typ<>arraydef) and
-           is_array_constructor(left.resultdef) then
+           is_array_constructor(left.resultdef) and 
+           (search_assignment_operator(left.resultdef,resultdef,nf_explicit in flags)=nil) then
           begin
             arrayconstructor_to_set(left);
             typecheckpass(left);
-- 
2.17.2 (Apple Git-113)

patch.diff (1,165 bytes)

Ryan Joseph

2019-03-23 18:05

reporter   ~0114994

Does this fix work or have unintended consequences? All I did in ncnv.pas was check if the right side node returned nil with search_assignment_operator before converting to a set.

{ convert array constructors to sets unless there is an assignment operator }
        if (resultdef.typ<>arraydef) and
           is_array_constructor(left.resultdef) and
           (search_assignment_operator(left.resultdef,resultdef,nf_explicit in flags)=nil) then
          begin
            arrayconstructor_to_set(left);
            typecheckpass(left);
          end;

Sven Barth

2019-04-05 17:25

manager   ~0115243

Things got a bit more complicated than that, cause I wanted to avoid the duplicate call of search_assignment_operator(). ;)

Please test and close if okay.

Issue History

Date Modified Username Field Change
2018-11-08 02:42 Ryan Joseph New Issue
2019-03-23 18:03 Ryan Joseph File Added: patch.diff
2019-03-23 18:05 Ryan Joseph Note Added: 0114994
2019-03-24 17:08 Sven Barth Relationship added has duplicate 0035061
2019-04-05 17:25 Sven Barth Fixed in Revision => 41844
2019-04-05 17:25 Sven Barth Note Added: 0115243
2019-04-05 17:25 Sven Barth Status new => resolved
2019-04-05 17:25 Sven Barth Fixed in Version => 3.3.1
2019-04-05 17:25 Sven Barth Resolution open => fixed
2019-04-05 17:25 Sven Barth Assigned To => Sven Barth
2019-04-06 16:30 Ryan Joseph Status resolved => closed