Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
68a5d5d7
Commit
68a5d5d7
authored
Sep 27, 2014
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix a reference leak for non-simple conditions in boolean and/or expressions
parent
37eea7a5
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
70 additions
and
5 deletions
+70
-5
CHANGES.rst
CHANGES.rst
+2
-0
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+14
-3
tests/run/boolop.pyx
tests/run/boolop.pyx
+29
-2
tests/run/boolop_py.py
tests/run/boolop_py.py
+25
-0
No files found.
CHANGES.rst
View file @
68a5d5d7
...
...
@@ -16,6 +16,8 @@ Features added
Bugs fixed
----------
* Reference leak for non-simple Python expressions in boolean and/or expressions.
* ``getitimer()``, ``setitimer()``, ``gettimeofday()`` and related type/constant
definitions were moved from ``posix/time.pxd`` to ``posix/sys_time.pxd`` to
fix a naming collision.
...
...
Cython/Compiler/ExprNodes.py
View file @
68a5d5d7
...
...
@@ -10039,20 +10039,30 @@ class BoolBinopResultNode(ExprNode):
self
.
arg
.
generate_evaluation_code
(
code
)
if
and_label
or
or_label
:
test_result
,
uses_temp
=
self
.
generate_operand_test
(
code
)
if
uses_temp
and
(
and_label
and
or_label
):
# cannot become final result => free early
# disposal: uses_temp and (and_label and or_label)
self
.
arg
.
generate_disposal_code
(
code
)
sense
=
'!'
if
or_label
else
''
code
.
putln
(
"if (%s%s) {"
%
(
sense
,
test_result
))
if
uses_temp
:
code
.
funcstate
.
release_temp
(
test_result
)
self
.
arg
.
generate_disposal_code
(
code
)
if
not
uses_temp
or
not
(
and_label
and
or_label
):
# disposal: (not uses_temp) or {not (and_label and or_label) [if]}
self
.
arg
.
generate_disposal_code
(
code
)
if
or_label
and
or_label
!=
fall_through
:
# value is false => short-circuit to next 'or'
code
.
put_goto
(
or_label
)
if
and_label
and
and_label
!=
fall_through
:
if
and_label
:
# value is true => go to next 'and'
if
or_label
:
code
.
putln
(
"} else {"
)
code
.
put_goto
(
and_label
)
if
not
uses_temp
:
# disposal: (not uses_temp) and {(and_label and or_label) [else]}
self
.
arg
.
generate_disposal_code
(
code
)
if
and_label
!=
fall_through
:
code
.
put_goto
(
and_label
)
if
not
and_label
or
not
or_label
:
# if no next 'and' or 'or', we provide the result
...
...
@@ -10062,6 +10072,7 @@ class BoolBinopResultNode(ExprNode):
self
.
value
.
make_owned_reference
(
code
)
code
.
putln
(
"%s = %s;"
%
(
final_result_temp
,
self
.
value
.
result
()))
self
.
value
.
generate_post_assignment_code
(
code
)
# disposal: {not (and_label and or_label) [else]}
self
.
arg
.
generate_disposal_code
(
code
)
self
.
value
.
free_temps
(
code
)
if
end_label
!=
fall_through
:
...
...
tests/run/boolop.pyx
View file @
68a5d5d7
def
foo
(
obj1
,
obj2
,
obj3
,
obj4
,
obj5
):
def
simple_values
(
obj1
,
obj2
,
obj3
,
obj4
):
"""
>>>
foo(True, False, 23, 'test', 1
)
>>>
simple_values(True, False, 23, 'test'
)
(0.0, 1.0, False, False)
"""
cdef
int
bool1
,
bool2
...
...
@@ -22,3 +23,29 @@ def foo(obj1, obj2, obj3, obj4, obj5):
obj4
=
obj1
and
obj2
and
obj3
obj5
=
(
obj1
+
obj2
+
obj3
)
and
obj4
return
bool3
,
bool4
,
obj4
,
obj5
def
non_simple_values
(
obj1
,
obj2
,
obj3
,
obj4
):
"""
>>> non_simple_values(1, 2, 3, 4)
(7, 3, 7, 3, 7, 7, 5, 5)
>>> non_simple_values(0, 0, 3, 4)
(0, 7, 4, 4, 4, 4, 4, 4)
>>> non_simple_values(0, 0, 1, -1)
(0, 0, -1, 0, -1, -1, 0, 0)
>>> non_simple_values(1, -1, 1, -1)
(0, 0, 0, 0, 0, 0, 0, 0)
>>> non_simple_values(1, 2, 1, -1)
(0, 3, 0, 3, 0, 0, 1, 1)
>>> non_simple_values(2, 1, 1, -1)
(0, 3, 1, 3, 0, 0, 1, 1)
"""
and1
=
obj1
+
obj2
and
obj3
+
obj4
or1
=
obj1
+
obj2
or
obj3
+
obj4
and_or
=
obj1
+
obj2
and
obj3
+
obj4
or
obj1
+
obj4
or_and
=
obj1
+
obj2
or
obj3
+
obj4
and
obj1
+
obj4
and_or_and
=
obj1
+
obj2
and
obj3
+
obj4
or
obj1
+
obj4
and
obj2
+
obj4
and1_or_and
=
(
and1
or
(
obj1
+
obj4
and
obj2
+
obj4
))
or_and_or
=
(
obj1
+
obj2
or
obj3
+
obj4
)
and
(
obj1
+
obj4
or
obj2
+
obj4
)
or1_and_or
=
(
or1
and
(
obj1
+
obj4
or
obj2
+
obj4
))
return
(
and1
,
or1
,
and_or
,
or_and
,
and_or_and
,
and1_or_and
,
or_and_or
,
or1_and_or
)
tests/run/boolop_py.py
0 → 100644
View file @
68a5d5d7
def
non_simple_values
(
obj1
,
obj2
,
obj3
,
obj4
):
"""
>>> non_simple_values(1, 2, 3, 4)
(7, 3, 7, 3, 7, 7, 5, 5)
>>> non_simple_values(0, 0, 3, 4)
(0, 7, 4, 4, 4, 4, 4, 4)
>>> non_simple_values(0, 0, 1, -1)
(0, 0, -1, 0, -1, -1, 0, 0)
>>> non_simple_values(1, -1, 1, -1)
(0, 0, 0, 0, 0, 0, 0, 0)
>>> non_simple_values(1, 2, 1, -1)
(0, 3, 0, 3, 0, 0, 1, 1)
>>> non_simple_values(2, 1, 1, -1)
(0, 3, 1, 3, 0, 0, 1, 1)
"""
and1
=
obj1
+
obj2
and
obj3
+
obj4
or1
=
obj1
+
obj2
or
obj3
+
obj4
and_or
=
obj1
+
obj2
and
obj3
+
obj4
or
obj1
+
obj4
or_and
=
obj1
+
obj2
or
obj3
+
obj4
and
obj1
+
obj4
and_or_and
=
obj1
+
obj2
and
obj3
+
obj4
or
obj1
+
obj4
and
obj2
+
obj4
and1_or_and
=
(
and1
or
(
obj1
+
obj4
and
obj2
+
obj4
))
or_and_or
=
(
obj1
+
obj2
or
obj3
+
obj4
)
and
(
obj1
+
obj4
or
obj2
+
obj4
)
or1_and_or
=
(
or1
and
(
obj1
+
obj4
or
obj2
+
obj4
))
return
(
and1
,
or1
,
and_or
,
or_and
,
and_or_and
,
and1_or_and
,
or_and_or
,
or1_and_or
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment