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:
--- /dev/null
+# 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