Skip to content

Commit

Permalink
Fix dict assignment to reserved struct member names.
Browse files Browse the repository at this point in the history
  • Loading branch information
scoder committed Sep 27, 2024
1 parent 3dc8116 commit bcb28ab
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
18 changes: 9 additions & 9 deletions Cython/Compiler/ExprNodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9442,6 +9442,9 @@ def generate_evaluation_code(self, code):
len(self.key_value_pairs),
code.error_goto_if_null(self.result(), self.pos)))
self.generate_gotref(code)
struct_scope = None
else:
struct_scope = self.type.scope

keys_seen = set()
key_type = None
Expand Down Expand Up @@ -9490,17 +9493,14 @@ def generate_evaluation_code(self, code):
if self.exclude_null_values:
code.putln('}')
else:
member = struct_scope.lookup_here(item.key.value)
assert member is not None, f"struct member {member} not found, error was not handled during coercion"
key_cname = member.cname
value_cname = item.value.result()
if item.value.type.is_array:
code.putln("memcpy(%s.%s, %s, sizeof(%s));" % (
self.result(),
item.key.value,
item.value.result(),
item.value.result()))
code.putln(f"memcpy({self.result()}.{key_cname}, {value_cname}, sizeof({value_cname}));")
else:
code.putln("%s.%s = %s;" % (
self.result(),
item.key.value,
item.value.result()))
code.putln(f"{self.result()}.{key_cname} = {value_cname};")
item.generate_disposal_code(code)
item.free_temps(code)

Expand Down
24 changes: 24 additions & 0 deletions tests/run/cstruct.pyx
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
# mode: run
#tag: struct

cdef struct Grail


cdef struct Spam:
int i
char c
float *p[42]
Grail *g


cdef struct Grail:
Spam *s


cdef struct ReservedNames:
int new
int case
int do


cdef Spam spam, ham

cdef void eggs_i(Spam s):
Expand Down Expand Up @@ -81,3 +93,15 @@ def assign_fields_in_loop():

assert s.a == s.b
return s.b


def reserved_names():
"""
>>> reserved_names()
(2, 5, 9)
"""
cdef ReservedNames s1 = ReservedNames(new=2, case=5, do=9)
cdef ReservedNames s2
s2.new = s1.new
s2.case, s2.do = s1.case, s1.do
return (s2.new, s2.case, s2.do)

0 comments on commit bcb28ab

Please sign in to comment.