diff --git a/python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll b/python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll index 78218f489215..7e653c7b9a16 100644 --- a/python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll +++ b/python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll @@ -1626,6 +1626,8 @@ private module Input implements InputSig1, InputSig2 { n = any(Ast::AssertStmt a).getTest() } + predicate postOrInOrder(Ast::AstNode n) { mayThrow(n) } + private string assertThrowTag() { result = "[assert-throw]" } /** diff --git a/python/ql/test/library-tests/ControlFlow/shared-cfg-exceptions/ExceptionReachabilityTest.expected b/python/ql/test/library-tests/ControlFlow/shared-cfg-exceptions/ExceptionReachabilityTest.expected new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/ql/test/library-tests/ControlFlow/shared-cfg-exceptions/ExceptionReachabilityTest.ql b/python/ql/test/library-tests/ControlFlow/shared-cfg-exceptions/ExceptionReachabilityTest.ql new file mode 100644 index 000000000000..c98e73336676 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/shared-cfg-exceptions/ExceptionReachabilityTest.ql @@ -0,0 +1,29 @@ +/** + * Inline-expectations test for exception-handler reachability in the shared CFG. + */ + +import python +import semmle.python.controlflow.internal.AstNodeImpl as CfgImpl +import semmle.python.controlflow.internal.Cfg as Cfg +import utils.test.InlineExpectationsTest + +module ExceptionReachabilityTest implements TestSig { + string getARelevantTag() { result = "exception-handler" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists( + Expr source, ExceptStmt handler, Cfg::ControlFlowNode sourceCfg, + Cfg::ControlFlowNode handlerEntry + | + sourceCfg.getNode() = source and + handlerEntry = sourceCfg.getAnExceptionalSuccessor() and + CfgImpl::astNodeToPyNode(handlerEntry.getAstNode()) = handler and + location = source.getLocation() and + element = source.toString() and + tag = "exception-handler" and + value = handler.getType().toString() + ) + } +} + +import MakeTest diff --git a/python/ql/test/library-tests/ControlFlow/shared-cfg-exceptions/test.py b/python/ql/test/library-tests/ControlFlow/shared-cfg-exceptions/test.py new file mode 100644 index 000000000000..0e55eba97407 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/shared-cfg-exceptions/test.py @@ -0,0 +1,12 @@ +def generator(): + try: + yield # $ exception-handler=GeneratorExit + except GeneratorExit: + return + + +def load_module(): + try: + import unavailable_module # $ exception-handler=ImportError + except ImportError: + return None