Commit 1006500a authored by Ian Henriksen's avatar Ian Henriksen

Add proper special casing for assignment to a C++ class from an object of

a different type using an overloaded assignment operator.
parent 7e803a0f
...@@ -1992,7 +1992,7 @@ class NameNode(AtomicExprNode): ...@@ -1992,7 +1992,7 @@ class NameNode(AtomicExprNode):
if null_code and raise_unbound and (entry.type.is_pyobject or memslice_check): if null_code and raise_unbound and (entry.type.is_pyobject or memslice_check):
code.put_error_if_unbound(self.pos, entry, self.in_nogil_context) code.put_error_if_unbound(self.pos, entry, self.in_nogil_context)
def generate_assignment_code(self, rhs, code): def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
#print "NameNode.generate_assignment_code:", self.name ### #print "NameNode.generate_assignment_code:", self.name ###
entry = self.entry entry = self.entry
if entry is None: if entry is None:
...@@ -2082,8 +2082,11 @@ class NameNode(AtomicExprNode): ...@@ -2082,8 +2082,11 @@ class NameNode(AtomicExprNode):
code.put_giveref(rhs.py_result()) code.put_giveref(rhs.py_result())
if not self.type.is_memoryviewslice: if not self.type.is_memoryviewslice:
if not assigned: if not assigned:
code.putln('%s = %s;' % ( if overloaded_assignment:
self.result(), rhs.result_as(self.ctype()))) code.putln('%s = %s;' % (self.result(), rhs.result()))
else:
code.putln('%s = %s;' % (
self.result(), rhs.result_as(self.ctype())))
if debug_disposal_code: if debug_disposal_code:
print("NameNode.generate_assignment_code:") print("NameNode.generate_assignment_code:")
print("...generating post-assignment code for %s" % rhs) print("...generating post-assignment code for %s" % rhs)
......
...@@ -4760,12 +4760,14 @@ class SingleAssignmentNode(AssignmentNode): ...@@ -4760,12 +4760,14 @@ class SingleAssignmentNode(AssignmentNode):
# #
# a = b # a = b
# #
# lhs ExprNode Left hand side # lhs ExprNode Left hand side
# rhs ExprNode Right hand side # rhs ExprNode Right hand side
# first bool Is this guaranteed the first assignment to lhs? # first bool Is this guaranteed the first assignment to lhs?
# is_overloaded_assignment bool Is this assignment done via an overloaded operator=
child_attrs = ["lhs", "rhs"] child_attrs = ["lhs", "rhs"]
first = False first = False
is_overloaded_assignment = False
declaration_only = False declaration_only = False
def analyse_declarations(self, env): def analyse_declarations(self, env):
...@@ -4882,7 +4884,15 @@ class SingleAssignmentNode(AssignmentNode): ...@@ -4882,7 +4884,15 @@ class SingleAssignmentNode(AssignmentNode):
else: else:
dtype = self.lhs.type dtype = self.lhs.type
rhs = self.rhs.coerce_to(dtype, env) if self.lhs.type.is_cpp_class:
op = env.lookup_operator_for_types(self.pos, '=', [self.lhs.type, self.rhs.type])
if op:
rhs = self.rhs
self.is_overloaded_assignment = 1
else:
rhs = self.rhs.coerce_to(dtype, env)
else:
rhs = self.rhs.coerce_to(dtype, env)
if use_temp or rhs.is_attribute or ( if use_temp or rhs.is_attribute or (
not rhs.is_name and not rhs.is_literal and not rhs.is_name and not rhs.is_literal and
rhs.type.is_pyobject): rhs.type.is_pyobject):
...@@ -5030,7 +5040,11 @@ class SingleAssignmentNode(AssignmentNode): ...@@ -5030,7 +5040,11 @@ class SingleAssignmentNode(AssignmentNode):
self.rhs.generate_evaluation_code(code) self.rhs.generate_evaluation_code(code)
def generate_assignment_code(self, code): def generate_assignment_code(self, code):
self.lhs.generate_assignment_code(self.rhs, code) if self.is_overloaded_assignment:
self.lhs.generate_assignment_code(self.rhs, code, overloaded_assignment=True)
else:
self.lhs.generate_assignment_code(self.rhs, code)
def generate_function_definitions(self, env, code): def generate_function_definitions(self, env, code):
self.rhs.generate_function_definitions(env, code) self.rhs.generate_function_definitions(env, code)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment