Commit 3c3e4564 authored by Stefan Behnel's avatar Stefan Behnel

reduce impact of 'unsafe C derivative' error to pointers and fix conditional expressions

parent eb637f5e
......@@ -9755,6 +9755,9 @@ class CondExprNode(ExprNode):
else:
self.constant_result = self.false_val.constant_result
def is_ephemeral(self):
return self.true_val.is_ephemeral() or self.false_val.is_ephemeral()
def analyse_types(self, env):
self.test = self.test.analyse_types(env).coerce_to_boolean(env)
self.true_val = self.true_val.analyse_types(env)
......@@ -9767,6 +9770,8 @@ class CondExprNode(ExprNode):
self.true_val.type, self.false_val.type)
if self.type.is_pyobject:
self.result_ctype = py_object_type
elif self.true_val.is_ephemeral() or self.false_val.is_ephemeral():
error(self.pos, "Unsafe C derivative of temporary Python reference used in conditional expression")
if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
self.true_val = self.true_val.coerce_to(self.type, env)
self.false_val = self.false_val.coerce_to(self.type, env)
......@@ -9798,7 +9803,7 @@ class CondExprNode(ExprNode):
code.mark_pos(self.pos)
self.allocate_temp_result(code)
self.test.generate_evaluation_code(code)
code.putln("if (%s) {" % self.test.result() )
code.putln("if (%s) {" % self.test.result())
self.eval_and_get(code, self.true_val)
code.putln("} else {")
self.eval_and_get(code, self.false_val)
......@@ -9813,6 +9818,13 @@ class CondExprNode(ExprNode):
expr.generate_post_assignment_code(code)
expr.free_temps(code)
def generate_subexpr_disposal_code(self, code):
pass # done explicitly above (cleanup must separately happen within the if/else blocks)
def free_subexpr_temps(self, code):
pass # done explicitly above (cleanup must separately happen within the if/else blocks)
richcmp_constants = {
"<" : "Py_LT",
"<=": "Py_LE",
......
......@@ -4559,7 +4559,7 @@ class AssignmentNode(StatNode):
def analyse_expressions(self, env):
node = self.analyse_types(env)
if isinstance(node, AssignmentNode):
if not node.rhs.type.is_pyobject and node.rhs.is_ephemeral():
if node.rhs.type.is_ptr and node.rhs.is_ephemeral():
error(self.pos, "Storing unsafe C derivative of temporary Python reference")
return node
......
......@@ -44,6 +44,14 @@ cuptr = u
cuptr = u + u"cba"
# coercion in conditional expression => ok
boolval = list(u)
cptr = c_s if boolval else c_s
# temp in conditional expression => error
cptr = s + b'x' if boolval else s + b'y'
_ERRORS = """
16:8: Obtaining 'char *' from externally modifiable global Python value
19:9: Storing unsafe C derivative of temporary Python reference
......@@ -53,4 +61,6 @@ _ERRORS = """
26:8: Storing unsafe C derivative of temporary Python reference
41:9: Obtaining 'Py_UNICODE *' from externally modifiable global Python value
44:10: Storing unsafe C derivative of temporary Python reference
52:7: Storing unsafe C derivative of temporary Python reference
52:7: Unsafe C derivative of temporary Python reference used in conditional expression
"""
......@@ -40,5 +40,5 @@ def test_charptr_coercion(x):
>>> print(test_charptr_coercion(False))
def
"""
cdef char* s = 'abc' if x else 'def'
cdef char* s = b'abc' if x else b'def'
return s.decode('ascii')
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