transforms.artiq_ir_generator: handle terminated try body.

This commit is contained in:
whitequark 2015-12-31 22:23:13 +08:00
parent 71d8cbb431
commit 79d020dd3a
2 changed files with 24 additions and 11 deletions

View File

@ -150,14 +150,21 @@ class ARTIQIRGenerator(algorithm.Visitor):
else: else:
insn.drop_references() insn.drop_references()
def warn_unreachable(self, node):
diag = diagnostic.Diagnostic("warning",
"unreachable code", {},
node.loc.begin())
self.engine.process(diag)
# Visitors # Visitors
def visit(self, obj): def visit(self, obj):
if isinstance(obj, list): if isinstance(obj, list):
for elt in obj: for elt in obj:
self.visit(elt)
if self.current_block.is_terminated(): if self.current_block.is_terminated():
self.warn_unreachable(elt)
break break
self.visit(elt)
elif isinstance(obj, ast.AST): elif isinstance(obj, ast.AST):
try: try:
old_loc, self.current_loc = self.current_loc, _extract_loc(obj) old_loc, self.current_loc = self.current_loc, _extract_loc(obj)
@ -615,7 +622,10 @@ class ARTIQIRGenerator(algorithm.Visitor):
finally: finally:
self.unwind_target = old_unwind self.unwind_target = old_unwind
self.visit(node.orelse) if not body.is_terminated():
self.visit(node.orelse)
elif any(node.orelse):
self.warn_unreachable(node.orelse[0])
body = self.current_block body = self.current_block
if any(node.finalbody): if any(node.finalbody):

View File

@ -1,4 +1,4 @@
import os import os, sys
from pythonparser import diagnostic from pythonparser import diagnostic
@ -13,21 +13,24 @@ from artiq.compiler.targets import OR1KTarget
# Import for side effects (creating the exception classes). # Import for side effects (creating the exception classes).
from artiq.coredevice import exceptions from artiq.coredevice import exceptions
def _render_diagnostic(diagnostic):
def shorten_path(path):
return path.replace(os.path.normpath(os.path.join(__file__, "..", "..")), "<artiq>")
lines = [shorten_path(path) for path in diagnostic.render(colored=True)]
return "\n".join(lines)
class _DiagnosticEngine(diagnostic.Engine):
def print_diagnostic(self, diagnostic):
sys.stderr.write(_render_diagnostic(diagnostic) + "\n")
class CompileError(Exception): class CompileError(Exception):
def __init__(self, diagnostic): def __init__(self, diagnostic):
self.diagnostic = diagnostic self.diagnostic = diagnostic
def render_string(self, colored=False):
def shorten_path(path):
return path.replace(os.path.normpath(os.path.join(__file__, "..", "..")), "<artiq>")
lines = [shorten_path(path) for path in self.diagnostic.render(colored=colored)]
return "\n".join(lines)
def __str__(self): def __str__(self):
# Prepend a newline so that the message shows up on after # Prepend a newline so that the message shows up on after
# exception class name printed by Python. # exception class name printed by Python.
return "\n" + self.render_string(colored=True) return "\n" + _render_diagnostic(self.diagnostic)
@syscall @syscall
@ -58,7 +61,7 @@ class Core:
def compile(self, function, args, kwargs, set_result=None, with_attr_writeback=True): def compile(self, function, args, kwargs, set_result=None, with_attr_writeback=True):
try: try:
engine = diagnostic.Engine(all_errors_are_fatal=True) engine = _DiagnosticEngine(all_errors_are_fatal=True)
stitcher = Stitcher(engine=engine) stitcher = Stitcher(engine=engine)
stitcher.stitch_call(function, args, kwargs, set_result) stitcher.stitch_call(function, args, kwargs, set_result)