@@ -112,6 +112,33 @@ class FlowSummaryIntermediateAwaitStoreNode extends DataFlow::Node,
112112 }
113113}
114114
115+ predicate mentionsExceptionalReturn ( FlowSummaryImpl:: Public:: SummarizedCallable callable ) {
116+ exists ( FlowSummaryImpl:: Private:: SummaryNode node | node .getSummarizedCallable ( ) = callable |
117+ FlowSummaryImpl:: Private:: summaryReturnNode ( node , MkExceptionalReturnKind ( ) )
118+ or
119+ FlowSummaryImpl:: Private:: summaryOutNode ( _, node , MkExceptionalReturnKind ( ) )
120+ )
121+ }
122+
123+ /**
124+ * Exceptional return node in a summarized callable whose summary does not mention `ReturnValue[exception]`.
125+ *
126+ * By default, every call inside such a callable will forward their exceptional return to the caller's
127+ * exceptional return, i.e. exceptions are not caught.
128+ */
129+ class FlowSummaryDefaultExceptionalReturn extends DataFlow:: Node ,
130+ TFlowSummaryDefaultExceptionalReturn
131+ {
132+ private FlowSummaryImpl:: Public:: SummarizedCallable callable ;
133+
134+ FlowSummaryDefaultExceptionalReturn ( ) { this = TFlowSummaryDefaultExceptionalReturn ( callable ) }
135+
136+ FlowSummaryImpl:: Public:: SummarizedCallable getSummarizedCallable ( ) { result = callable }
137+
138+ cached
139+ override string toString ( ) { result = "[default exceptional return] " + callable }
140+ }
141+
115142class CaptureNode extends DataFlow:: Node , TSynthCaptureNode {
116143 /** Gets the underlying node from the variable-capture library. */
117144 VariableCaptureOutput:: SynthesizedCaptureNode getNode ( ) {
@@ -296,6 +323,9 @@ private predicate returnNodeImpl(DataFlow::Node node, ReturnKind kind) {
296323 )
297324 or
298325 FlowSummaryImpl:: Private:: summaryReturnNode ( node .( FlowSummaryNode ) .getSummaryNode ( ) , kind )
326+ or
327+ node instanceof FlowSummaryDefaultExceptionalReturn and
328+ kind = MkExceptionalReturnKind ( )
299329}
300330
301331private DataFlow:: Node getAnOutNodeImpl ( DataFlowCall call , ReturnKind kind ) {
@@ -311,6 +341,10 @@ private DataFlow::Node getAnOutNodeImpl(DataFlowCall call, ReturnKind kind) {
311341 or
312342 FlowSummaryImpl:: Private:: summaryOutNode ( call .( SummaryCall ) .getReceiver ( ) ,
313343 result .( FlowSummaryNode ) .getSummaryNode ( ) , kind )
344+ or
345+ kind = MkExceptionalReturnKind ( ) and
346+ result .( FlowSummaryDefaultExceptionalReturn ) .getSummarizedCallable ( ) =
347+ call .( SummaryCall ) .getSummarizedCallable ( )
314348}
315349
316350class ReturnNode extends DataFlow:: Node {
@@ -505,6 +539,8 @@ DataFlowCallable nodeGetEnclosingCallable(Node node) {
505539 or
506540 result .asLibraryCallable ( ) = node .( FlowSummaryIntermediateAwaitStoreNode ) .getSummarizedCallable ( )
507541 or
542+ result .asLibraryCallable ( ) = node .( FlowSummaryDefaultExceptionalReturn ) .getSummarizedCallable ( )
543+ or
508544 node = TGenericSynthesizedNode ( _, _, result )
509545}
510546
@@ -865,6 +901,8 @@ class SummaryCall extends DataFlowCall, MkSummaryCall {
865901
866902 /** Gets the receiver node. */
867903 FlowSummaryImpl:: Private:: SummaryNode getReceiver ( ) { result = receiver }
904+
905+ FlowSummaryImpl:: Public:: SummarizedCallable getSummarizedCallable ( ) { result = enclosingCallable }
868906}
869907
870908/**
0 commit comments