Commit bcba9251 authored by Gerald Dalley's avatar Gerald Dalley

Fixed IndexNode.is_lvalue

In C/C++, almost all index operator expressions return lvalues. We now
allow anything that doesn't look like it resolves to assigning to a
whole array object to be considered an lvalue.

Before this commit, using the index operator on containers that return
references would crash the Cython compiler.  run/tests/lvalue_refs.pyx
contains an example of code that previously crashed the compiler.

Author: Gerald Dalley
parent cbc0665c
......@@ -3193,11 +3193,22 @@ class IndexNode(ExprNode):
return self.base.check_const_addr() and self.index.check_const()
def is_lvalue(self):
base_type = self.base.type
if self.type.is_ptr or self.type.is_array:
return not base_type.base_type.is_array
else:
# NOTE: references currently have both is_reference and is_ptr
# set. Since pointers and references have different lvalue
# rules, we must be careful to separate the two.
if self.type.is_reference:
if self.type.ref_base_type.is_array:
# fixed-sized arrays aren't l-values
return False
elif self.type.is_ptr:
# non-const pointers can always be reassigned
return True
elif self.type.is_array:
# fixed-sized arrays aren't l-values
return False
# Just about everything else returned by the index operator
# can be an lvalue.
return True
def calculate_result_code(self):
if self.is_buffer_access:
......
# tag: cpp
from libcpp.vector cimport vector
__doc__ = u"""
>>> test_lvalue_ref_assignment()
"""
ctypedef double* dp
ctypedef double** dpp
cdef void foo(vector[dpp] &bar, vector[vector[dp]] &baz) nogil:
bar[0] = &baz[0][0]
def test_lvalue_ref_assignment():
cdef vector[dpp] bar
cdef vector[vector[dp]] baz
cdef vector[double] data
cdef dp bongle = &data[0]
bar.resize(1)
bar[0] = NULL
baz.resize(1)
baz[0].resize(1)
baz[0][0] = bongle
foo(bar, baz)
assert bar[0] == &baz[0][0]
assert bar[0][0] == bongle
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