@@ -214,9 +214,11 @@ module Flow<
214214 final private class CfgBb = Cfg:: BasicBlock ;
215215
216216 private class BasicBlock extends CfgBb {
217+ /** Gets the callable enclosing this basic block. */
217218 Callable getEnclosingCallable ( ) { result = basicBlockGetEnclosingCallable ( this ) }
218219 }
219220
221+ /** Provides consistency checks for an instantiation of the variable capture library. */
220222 additional module ConsistencyChecks {
221223 final private class FinalExpr = Expr ;
222224
@@ -250,6 +252,10 @@ module Flow<
250252 }
251253 }
252254
255+ /**
256+ * Holds if `n` relevant elements have either no textual representation or multiple textual
257+ * representations, as described by `msg`.
258+ */
253259 query predicate uniqueToString ( string msg , int n ) {
254260 exists ( string elem |
255261 n = strictcount ( RelevantBasicBlock bb | not exists ( bb .toString ( ) ) ) and
@@ -282,45 +288,72 @@ module Flow<
282288 )
283289 }
284290
291+ /**
292+ * Holds if `bb` does not have exactly one enclosing callable, as described by `msg`.
293+ */
285294 query predicate uniqueEnclosingCallable ( RelevantBasicBlock bb , string msg ) {
286295 msg = "BasicBlock has no enclosing callable" and not exists ( bb .getEnclosingCallable ( ) )
287296 or
288297 msg = "BasicBlock has multiple enclosing callables" and
289298 2 <= strictcount ( bb .getEnclosingCallable ( ) )
290299 }
291300
301+ /**
302+ * Holds if `bb` has multiple immediate dominators, as described by `msg`.
303+ */
292304 query predicate uniqueDominator ( RelevantBasicBlock bb , string msg ) {
293305 msg = "BasicBlock has multiple immediate dominators" and
294306 2 <= strictcount ( bb .getImmediateDominator ( ) )
295307 }
296308
309+ /**
310+ * Holds if an immediate dominator of `bb` belongs to a different callable, as described by
311+ * `msg`.
312+ */
297313 query predicate localDominator ( RelevantBasicBlock bb , string msg ) {
298314 msg = "BasicBlock has non-local dominator" and
299315 bb .getEnclosingCallable ( ) != bb .getImmediateDominator ( ) .( BasicBlock ) .getEnclosingCallable ( )
300316 }
301317
318+ /**
319+ * Holds if a successor of `bb` belongs to a different callable, as described by `msg`.
320+ */
302321 query predicate localSuccessor ( RelevantBasicBlock bb , string msg ) {
303322 msg = "BasicBlock has non-local successor" and
304323 bb .getEnclosingCallable ( ) != bb .getASuccessor ( ) .( BasicBlock ) .getEnclosingCallable ( )
305324 }
306325
326+ /**
327+ * Holds if captured variable `v` does not have exactly one defining callable, as described by
328+ * `msg`.
329+ */
307330 query predicate uniqueDefiningScope ( CapturedVariable v , string msg ) {
308331 msg = "CapturedVariable has no defining callable" and not exists ( v .getCallable ( ) )
309332 or
310333 msg = "CapturedVariable has multiple defining callables" and 2 <= strictcount ( v .getCallable ( ) )
311334 }
312335
336+ /**
337+ * Holds if `v` is classified as a captured variable but has no access from a capturing
338+ * callable, as described by `msg`.
339+ */
313340 query predicate variableIsCaptured ( CapturedVariable v , string msg ) {
314341 msg = "CapturedVariable is not captured" and
315342 not captureAccess ( v , _)
316343 }
317344
345+ /**
346+ * Holds if relevant expression `e` does not have exactly one location, as described by `msg`.
347+ */
318348 query predicate uniqueLocation ( RelevantExpr e , string msg ) {
319349 msg = "Expr has no location" and not exists ( e .getLocation ( ) )
320350 or
321351 msg = "Expr has multiple locations" and 2 <= strictcount ( e .getLocation ( ) )
322352 }
323353
354+ /**
355+ * Holds if relevant expression `e` does not have exactly one CFG node, as described by `msg`.
356+ */
324357 query predicate uniqueCfgNode ( RelevantExpr e , string msg ) {
325358 msg = "Expr has no cfg node" and not e .hasCfgNode ( _, _)
326359 or
@@ -334,6 +367,10 @@ module Flow<
334367 msg = "VariableWrite has multiple target variables" and 2 <= strictcount ( vw .getVariable ( ) )
335368 }
336369
370+ /**
371+ * Holds if a captured-variable write does not have exactly one target variable, as described
372+ * by `msg`.
373+ */
337374 query predicate uniqueWriteTarget ( string msg ) { uniqueWriteTarget ( _, msg ) }
338375
339376 private predicate uniqueWriteCfgNode ( VariableWrite vw , string msg ) {
@@ -343,18 +380,33 @@ module Flow<
343380 2 <= strictcount ( BasicBlock bb , int i | vw .hasCfgNode ( bb , i ) )
344381 }
345382
383+ /**
384+ * Holds if a captured-variable write does not have exactly one CFG node, as described by
385+ * `msg`.
386+ */
346387 query predicate uniqueWriteCfgNode ( string msg ) { uniqueWriteCfgNode ( _, msg ) }
347388
389+ /**
390+ * Holds if variable read `vr` does not have exactly one source variable, as described by
391+ * `msg`.
392+ */
348393 query predicate uniqueReadVariable ( VariableRead vr , string msg ) {
349394 msg = "VariableRead has no source variable" and not exists ( vr .getVariable ( ) )
350395 or
351396 msg = "VariableRead has multiple source variables" and 2 <= strictcount ( vr .getVariable ( ) )
352397 }
353398
399+ /**
400+ * Holds if closure expression `ce` has no callable body, as described by `msg`.
401+ */
354402 query predicate closureMustHaveBody ( ClosureExpr ce , string msg ) {
355403 msg = "ClosureExpr has no body" and not ce .hasBody ( _)
356404 }
357405
406+ /**
407+ * Holds if `access` is an alias of closure expression `ce` outside the lexical scope of `ce`,
408+ * as described by `msg`.
409+ */
358410 query predicate closureAliasMustBeInSameScope ( ClosureExpr ce , Expr access , string msg ) {
359411 exists ( BasicBlock bb1 , BasicBlock bb2 |
360412 ce .hasAliasedAccess ( access ) and
@@ -372,6 +424,10 @@ module Flow<
372424 )
373425 }
374426
427+ /**
428+ * Holds if callable `c` accesses captured variable `v` but is not lexically nested in the
429+ * callable that defines `v`, as described by `msg`.
430+ */
375431 query predicate variableAccessAstNesting ( CapturedVariable v , Callable c , string msg ) {
376432 exists ( BasicBlock bb , Callable parent |
377433 captureRead ( v , bb , _, false , _) or captureWrite ( v , bb , _, false , _)
@@ -383,6 +439,9 @@ module Flow<
383439 )
384440 }
385441
442+ /**
443+ * Holds if relevant callable `c` does not have exactly one location, as described by `msg`.
444+ */
386445 query predicate uniqueCallableLocation ( RelevantCallable c , string msg ) {
387446 msg = "Callable has no location" and not exists ( c .getLocation ( ) )
388447 or
@@ -391,6 +450,9 @@ module Flow<
391450
392451 import SsaFlow:: DfConsistency
393452
453+ /**
454+ * Holds if `n` elements violate a variable capture consistency check, as described by `msg`.
455+ */
394456 query predicate consistencyOverview ( string msg , int n ) {
395457 uniqueToString ( msg , n ) or
396458 n = strictcount ( BasicBlock bb | uniqueEnclosingCallable ( bb , msg ) ) or
@@ -799,6 +861,7 @@ module Flow<
799861 private class TSynthesizedCaptureNode = TSynthRead or TSynthThisQualifier or TSynthSsa ;
800862
801863 class SynthesizedCaptureNode extends ClosureNode , TSynthesizedCaptureNode {
864+ /** Gets the basic block containing this synthesized capture node. */
802865 BasicBlock getBasicBlock ( ) {
803866 this = TSynthRead ( _, result , _, _)
804867 or
@@ -821,6 +884,9 @@ module Flow<
821884 exists ( SsaFlow:: SsaNode n | this = TSynthSsa ( n ) and n .getSourceVariable ( ) = TThis ( _) )
822885 }
823886
887+ /**
888+ * Holds if this is the synthesized capture node at index `i` in basic block `bb`.
889+ */
824890 predicate hasCfgNode ( BasicBlock bb , int i ) {
825891 this = TSynthRead ( _, bb , i , _)
826892 or
0 commit comments