Skip to content

[BUG] Type with a member and defined operator=: (out this, t : int ) produces an assignment operator with an initializer list #290

Closed

Description

@filipsajdak

In the current implementation of cppfront (fbf55ad) the following code:

element: type = {
    children: std::vector<int> = ();

    operator=: (out this, t : int ) = {
    }
}

Generates:

#define CPP2_USE_MODULES         Yes

#include "cpp2util.h"


#line 1 "../tests/bug_assignement_operator.cpp2"
class element;

//=== Cpp2 definitions ==========================================================

#line 1 "../tests/bug_assignement_operator.cpp2"
class element  {
    private: std::vector<int> children {}; 

    public: explicit element(cpp2::in<int> t){
    }
#line 4 "../tests/bug_assignement_operator.cpp2"
    public: auto operator=(cpp2::in<int> t) -> element& 
    : children{  }
#line 5 "../tests/bug_assignement_operator.cpp2"
{   
    return *this;
#line 6 "../tests/bug_assignement_operator.cpp2"
}};

The issue is that the assignment operator has an initializer list and fails to compile with the error:

../tests/bug_assignement_operator.cpp2... ok (all Cpp2, passes safety checks)

../tests/bug_assignement_operator.cpp2:5:5: error: only constructors take base initializers
    : children{  }
    ^
1 error generated.

Activity

  1. changed the title [-][BUG] Type with a member and defined `operator=: (out this, t : int )` produces assignment operator with initialiser list[/-] [+][BUG] Type with a member and defined `operator=: (out this, t : int )` produces an assignment operator with an initializer list[/+] on Mar 24, 2023
  2. filipsajdak commented on Mar 27, 2023

    @filipsajdak
    ContributorAuthor

    Similarly to #291 you can make this work by resigning from using the default initializer. The following code works:

    element: type = {
        children: std::vector<int>;
    
        operator=: (out this, t : int ) = {
            children = std::vector<int>();
        }
    }

    also it is worth noting that I would prefer to write:

        operator=: (out this, t : int ) = {
            children = (1,2,3);
        }

    to initialize children with values 1,2,3. Unfortunately that generates to the following code:

        public: explicit element(cpp2::in<int> t)
            : children{ 1, 2, 3 }
    #line 5 "../tests/bug_assignement_operator.cpp2"
    {
        }
    #line 4 "../tests/bug_assignement_operator.cpp2"
        public: auto operator=(cpp2::in<int> t) -> element& {
            children = 1, 2, 3;
    #line 5 "../tests/bug_assignement_operator.cpp2"
            
            return *this;
    #line 6 "../tests/bug_assignement_operator.cpp2"
        }

    Constructor is fine - it is using initializer list to initialize the vector with 1,2,3. The assignment is bad:

            children = 1, 2, 3;

    Workaround for this will be using:

            children = std::vector<int>(1,2,3);

    That will generate:

    class element  {
        private: std::vector<int> children {}; 
    
        public: explicit element(cpp2::in<int> t)
            : children{ std::vector<int>(1, 2, 3) }
    #line 4 "/Users/filipsajdak/dev/execspec/external/tests/bug_assignement_operator.cpp2"
                                        {
    
        }
    #line 4 "/Users/filipsajdak/dev/execspec/external/tests/bug_assignement_operator.cpp2"
        public: auto operator=(cpp2::in<int> t) -> element& {
            children = std::vector<int>(1, 2, 3);
            return *this;
    #line 6 "/Users/filipsajdak/dev/execspec/external/tests/bug_assignement_operator.cpp2"
        }
    };
  3. hsutter commented on Apr 1, 2023

    @hsutter
    Owner

    Thanks! Fixed.

    See also the comment in the closing commit for more information about a Clang warning that my fix now generates, but that I think is spurious.

  4. filipsajdak commented on Apr 2, 2023

    @filipsajdak
    ContributorAuthor

    @hsutter I confirmed. The issue is solved!

    The warning also appears with my compiler:

    ../tests/bug_assignement_operator.cpp2:9:16: warning: braces around scalar initializer [-Wbraced-scalar-init]
            name = {"Element"};
    
    Apple clang version 14.0.3 (clang-1403.0.22.14.1)
    Target: arm64-apple-darwin22.3.0
    Thread model: posix
    
  5. added a commit that references this issue on Dec 5, 2023
    dc411e6
  6. added a commit that references this issue on Feb 4, 2024
    feff640
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions