From 79d020dd3a1e4d507a8f925df8f2bb2c0d52577d Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 31 Dec 2015 22:23:13 +0800 Subject: [PATCH] transforms.artiq_ir_generator: handle terminated try body. --- .../compiler/transforms/artiq_ir_generator.py | 14 +++++++++++-- artiq/coredevice/core.py | 21 +++++++++++-------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/artiq/compiler/transforms/artiq_ir_generator.py b/artiq/compiler/transforms/artiq_ir_generator.py index 66958e544..3eb05a0a0 100644 --- a/artiq/compiler/transforms/artiq_ir_generator.py +++ b/artiq/compiler/transforms/artiq_ir_generator.py @@ -150,14 +150,21 @@ class ARTIQIRGenerator(algorithm.Visitor): else: insn.drop_references() + def warn_unreachable(self, node): + diag = diagnostic.Diagnostic("warning", + "unreachable code", {}, + node.loc.begin()) + self.engine.process(diag) + # Visitors def visit(self, obj): if isinstance(obj, list): for elt in obj: - self.visit(elt) if self.current_block.is_terminated(): + self.warn_unreachable(elt) break + self.visit(elt) elif isinstance(obj, ast.AST): try: old_loc, self.current_loc = self.current_loc, _extract_loc(obj) @@ -615,7 +622,10 @@ class ARTIQIRGenerator(algorithm.Visitor): finally: 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 if any(node.finalbody): diff --git a/artiq/coredevice/core.py b/artiq/coredevice/core.py index 35e23225a..81fd9c00f 100644 --- a/artiq/coredevice/core.py +++ b/artiq/coredevice/core.py @@ -1,4 +1,4 @@ -import os +import os, sys from pythonparser import diagnostic @@ -13,21 +13,24 @@ from artiq.compiler.targets import OR1KTarget # Import for side effects (creating the exception classes). from artiq.coredevice import exceptions +def _render_diagnostic(diagnostic): + def shorten_path(path): + return path.replace(os.path.normpath(os.path.join(__file__, "..", "..")), "") + 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): def __init__(self, diagnostic): self.diagnostic = diagnostic - def render_string(self, colored=False): - def shorten_path(path): - return path.replace(os.path.normpath(os.path.join(__file__, "..", "..")), "") - lines = [shorten_path(path) for path in self.diagnostic.render(colored=colored)] - return "\n".join(lines) - def __str__(self): # Prepend a newline so that the message shows up on after # exception class name printed by Python. - return "\n" + self.render_string(colored=True) + return "\n" + _render_diagnostic(self.diagnostic) @syscall @@ -58,7 +61,7 @@ class Core: def compile(self, function, args, kwargs, set_result=None, with_attr_writeback=True): try: - engine = diagnostic.Engine(all_errors_are_fatal=True) + engine = _DiagnosticEngine(all_errors_are_fatal=True) stitcher = Stitcher(engine=engine) stitcher.stitch_call(function, args, kwargs, set_result)