forked from M-Labs/artiq
1
0
Fork 0

compiler: Fix crash in escape analysis for assigning string literals

This commit is contained in:
David Nadlinger 2019-03-31 04:12:27 +01:00 committed by Sebastien Bourdeauducq
parent 56e14bfac7
commit ff1eb4858a
2 changed files with 19 additions and 13 deletions

View File

@ -51,10 +51,6 @@ class Region:
(other.range.begin_pos <= self.range.begin_pos <= other.range.end_pos and \ (other.range.begin_pos <= self.range.begin_pos <= other.range.end_pos and \
self.range.end_pos > other.range.end_pos) self.range.end_pos > other.range.end_pos)
def contract(self, other):
if not self.range:
self.range = other.range
def outlives(lhs, rhs): def outlives(lhs, rhs):
if not isinstance(lhs, Region): # lhs lives nonlexically if not isinstance(lhs, Region): # lhs lives nonlexically
return True return True
@ -69,8 +65,11 @@ class Region:
class RegionOf(algorithm.Visitor): class RegionOf(algorithm.Visitor):
""" """
Visit an expression and return the list of regions that must Visit an expression and return the region that must be alive for the
be alive for the expression to execute. expression to execute.
For expressions involving multiple regions, the shortest-lived one is
returned.
""" """
def __init__(self, env_stack, youngest_region): def __init__(self, env_stack, youngest_region):
@ -301,17 +300,20 @@ class EscapeValidator(algorithm.Visitor):
def visit_assignment(self, target, value): def visit_assignment(self, target, value):
value_region = self._region_of(value) value_region = self._region_of(value)
# If this is a variable, we might need to contract the live range.
if isinstance(value_region, Region):
for name in self._names_of(target):
region = self._region_of(name)
if isinstance(region, Region):
region.contract(value_region)
# If we assign to an attribute of a quoted value, there will be no names # If we assign to an attribute of a quoted value, there will be no names
# in the assignment lhs. # in the assignment lhs.
target_names = self._names_of(target) or [] target_names = self._names_of(target) or []
# Adopt the value region for any variables declared on the lhs.
for name in target_names:
region = self._region_of(name)
if isinstance(region, Region) and not region.present():
# Find the name's environment to overwrite the region.
for env in self.env_stack[::-1]:
if name.id in env:
env[name.id] = value_region
break
# The assigned value should outlive the assignee # The assigned value should outlive the assignee
target_regions = [self._region_of(name) for name in target_names] target_regions = [self._region_of(name) for name in target_names]
for target_region in target_regions: for target_region in target_regions:

View File

@ -9,3 +9,7 @@ def foo():
@kernel @kernel
def entrypoint(): def entrypoint():
foo() foo()
# Test reassigning strings.
a = "a"
b = a