Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1724,7 +1724,7 @@ private module Input implements InputSig1, InputSig2 {
always = true
or
mayThrow(ast) and
n.isIn(ast) and
n.injects(ast) and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think perhaps you need to add the relevant nodes to postOrInOrder instead. Otherwise, if these are leaf nodes, then you end up without a separate after-node, which means that unconditional exceptions cannot be represented.
(The fact that we have always = false may save us for now, but flipping that boolean wouldn't work, so it seems a bit too brittle.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess perhaps we could add a consistency check to verify that beginAbruptCompletion always sit on isIn or isAdditional nodes. I believe that's an implicit assumption by the library.

c.asSimpleAbruptCompletion() instanceof ExceptionSuccessor and
always = false
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<ExceptionReachabilityTest>
Original file line number Diff line number Diff line change
@@ -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
Loading