@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
28742874 }
28752875}
28762876
2877- /**
2878- * A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
2879- * Only those `PathNode`s that are reachable from a source are generated.
2880- */
2881- class PathNode extends TPathNode {
2882- /** Gets a textual representation of this element. */
2883- string toString ( ) { none ( ) }
2884-
2885- /**
2886- * Gets a textual representation of this element, including a textual
2887- * representation of the call context.
2888- */
2889- string toStringWithContext ( ) { none ( ) }
2890-
2891- /**
2892- * Holds if this element is at the specified location.
2893- * The location spans column `startcolumn` of line `startline` to
2894- * column `endcolumn` of line `endline` in file `filepath`.
2895- * For more information, see
2896- * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
2897- */
2898- predicate hasLocationInfo (
2899- string filepath , int startline , int startcolumn , int endline , int endcolumn
2900- ) {
2901- none ( )
2902- }
2903-
2904- /** Gets the underlying `Node`. */
2905- final Node getNode ( ) { this .( PathNodeImpl ) .getNodeEx ( ) .projectToNode ( ) = result }
2906-
2877+ abstract private class PathNodeImpl extends TPathNode {
29072878 /** Gets the `FlowState` of this node. */
2908- FlowState getState ( ) { none ( ) }
2879+ abstract FlowState getState ( ) ;
29092880
29102881 /** Gets the associated configuration. */
2911- Configuration getConfiguration ( ) { none ( ) }
2912-
2913- /** Gets a successor of this node, if any. */
2914- final PathNode getASuccessor ( ) {
2915- result = this .( PathNodeImpl ) .getANonHiddenSuccessor ( ) and
2916- reach ( this ) and
2917- reach ( result )
2918- }
2882+ abstract Configuration getConfiguration ( ) ;
29192883
29202884 /** Holds if this node is a source. */
2921- predicate isSource ( ) { none ( ) }
2922- }
2885+ abstract predicate isSource ( ) ;
29232886
2924- abstract private class PathNodeImpl extends PathNode {
29252887 abstract PathNodeImpl getASuccessorImpl ( ) ;
29262888
29272889 private PathNodeImpl getASuccessorIfHidden ( ) {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
29672929 result = " <" + this .( PathNodeMid ) .getCallContext ( ) .toString ( ) + ">"
29682930 }
29692931
2970- override string toString ( ) { result = this .getNodeEx ( ) .toString ( ) + this .ppAp ( ) }
2932+ /** Gets a textual representation of this element. */
2933+ string toString ( ) { result = this .getNodeEx ( ) .toString ( ) + this .ppAp ( ) }
29712934
2972- override string toStringWithContext ( ) {
2973- result = this .getNodeEx ( ) .toString ( ) + this .ppAp ( ) + this .ppCtx ( )
2974- }
2935+ /**
2936+ * Gets a textual representation of this element, including a textual
2937+ * representation of the call context.
2938+ */
2939+ string toStringWithContext ( ) { result = this .getNodeEx ( ) .toString ( ) + this .ppAp ( ) + this .ppCtx ( ) }
29752940
2976- override predicate hasLocationInfo (
2941+ /**
2942+ * Holds if this element is at the specified location.
2943+ * The location spans column `startcolumn` of line `startline` to
2944+ * column `endcolumn` of line `endline` in file `filepath`.
2945+ * For more information, see
2946+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
2947+ */
2948+ predicate hasLocationInfo (
29772949 string filepath , int startline , int startcolumn , int endline , int endcolumn
29782950 ) {
29792951 this .getNodeEx ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
29862958}
29872959
29882960/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
2989- private predicate reach ( PathNode n ) { directReach ( n ) or Subpaths:: retReach ( n ) }
2961+ private predicate reach ( PathNodeImpl n ) { directReach ( n ) or Subpaths:: retReach ( n ) }
29902962
29912963/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
2992- private predicate pathSucc ( PathNodeImpl n1 , PathNode n2 ) {
2964+ private predicate pathSucc ( PathNodeImpl n1 , PathNodeImpl n2 ) {
29932965 n1 .getANonHiddenSuccessor ( ) = n2 and directReach ( n2 )
29942966}
29952967
2996- private predicate pathSuccPlus ( PathNode n1 , PathNode n2 ) = fastTC( pathSucc / 2 ) ( n1 , n2 )
2968+ private predicate pathSuccPlus ( PathNodeImpl n1 , PathNodeImpl n2 ) = fastTC( pathSucc / 2 ) ( n1 , n2 )
2969+
2970+ /**
2971+ * A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
2972+ * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
2973+ */
2974+ class PathNode instanceof PathNodeImpl {
2975+ PathNode ( ) { reach ( this ) }
2976+
2977+ /** Gets a textual representation of this element. */
2978+ final string toString ( ) { result = super .toString ( ) }
2979+
2980+ /**
2981+ * Gets a textual representation of this element, including a textual
2982+ * representation of the call context.
2983+ */
2984+ final string toStringWithContext ( ) { result = super .toStringWithContext ( ) }
2985+
2986+ /**
2987+ * Holds if this element is at the specified location.
2988+ * The location spans column `startcolumn` of line `startline` to
2989+ * column `endcolumn` of line `endline` in file `filepath`.
2990+ * For more information, see
2991+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
2992+ */
2993+ final predicate hasLocationInfo (
2994+ string filepath , int startline , int startcolumn , int endline , int endcolumn
2995+ ) {
2996+ super .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
2997+ }
2998+
2999+ /** Gets the underlying `Node`. */
3000+ final Node getNode ( ) { super .getNodeEx ( ) .projectToNode ( ) = result }
3001+
3002+ /** Gets the `FlowState` of this node. */
3003+ final FlowState getState ( ) { result = super .getState ( ) }
3004+
3005+ /** Gets the associated configuration. */
3006+ final Configuration getConfiguration ( ) { result = super .getConfiguration ( ) }
3007+
3008+ /** Gets a successor of this node, if any. */
3009+ final PathNode getASuccessor ( ) { result = super .getANonHiddenSuccessor ( ) }
3010+
3011+ /** Holds if this node is a source. */
3012+ final predicate isSource ( ) { super .isSource ( ) }
3013+ }
29973014
29983015/**
29993016 * Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
30043021
30053022 /** Holds if `n` is a node in the graph of data flow path explanations. */
30063023 query predicate nodes ( PathNode n , string key , string val ) {
3007- reach ( n ) and key = "semmle.label" and val = n .toString ( )
3024+ key = "semmle.label" and val = n .toString ( )
30083025 }
30093026
30103027 /**
@@ -3013,11 +3030,7 @@ module PathGraph {
30133030 * `ret -> out` is summarized as the edge `arg -> out`.
30143031 */
30153032 query predicate subpaths ( PathNode arg , PathNode par , PathNode ret , PathNode out ) {
3016- Subpaths:: subpaths ( arg , par , ret , out ) and
3017- reach ( arg ) and
3018- reach ( par ) and
3019- reach ( ret ) and
3020- reach ( out )
3033+ Subpaths:: subpaths ( arg , par , ret , out )
30213034 }
30223035}
30233036
@@ -3399,22 +3412,22 @@ private module Subpaths {
33993412 */
34003413 pragma [ nomagic]
34013414 private predicate subpaths02 (
3402- PathNode arg , ParamNodeEx par , SummaryCtxSome sc , CallContext innercc , ReturnKindExt kind ,
3415+ PathNodeImpl arg , ParamNodeEx par , SummaryCtxSome sc , CallContext innercc , ReturnKindExt kind ,
34033416 NodeEx out , FlowState sout , AccessPath apout
34043417 ) {
34053418 subpaths01 ( arg , par , sc , innercc , kind , out , sout , apout ) and
34063419 out .asNode ( ) = kind .getAnOutNode ( _)
34073420 }
34083421
34093422 pragma [ nomagic]
3410- private Configuration getPathNodeConf ( PathNode n ) { result = n .getConfiguration ( ) }
3423+ private Configuration getPathNodeConf ( PathNodeImpl n ) { result = n .getConfiguration ( ) }
34113424
34123425 /**
34133426 * Holds if `(arg, par, ret, out)` forms a subpath-tuple.
34143427 */
34153428 pragma [ nomagic]
34163429 private predicate subpaths03 (
3417- PathNode arg , ParamNodeEx par , PathNodeMid ret , NodeEx out , FlowState sout , AccessPath apout
3430+ PathNodeImpl arg , ParamNodeEx par , PathNodeMid ret , NodeEx out , FlowState sout , AccessPath apout
34183431 ) {
34193432 exists ( SummaryCtxSome sc , CallContext innercc , ReturnKindExt kind , RetNodeEx retnode |
34203433 subpaths02 ( arg , par , sc , innercc , kind , out , sout , apout ) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
34443457 * a subpath between `par` and `ret` with the connecting edges `arg -> par` and
34453458 * `ret -> out` is summarized as the edge `arg -> out`.
34463459 */
3447- predicate subpaths ( PathNodeImpl arg , PathNodeImpl par , PathNodeImpl ret , PathNode out ) {
3460+ predicate subpaths ( PathNodeImpl arg , PathNodeImpl par , PathNodeImpl ret , PathNodeImpl out ) {
34483461 exists ( ParamNodeEx p , NodeEx o , FlowState sout , AccessPath apout , PathNodeMid out0 |
34493462 pragma [ only_bind_into ] ( arg ) .getANonHiddenSuccessor ( ) = pragma [ only_bind_into ] ( out0 ) and
34503463 subpaths03 ( pragma [ only_bind_into ] ( arg ) , p , localStepToHidden * ( ret ) , o , sout , apout ) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
34603473 * Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
34613474 */
34623475 predicate retReach ( PathNodeImpl n ) {
3463- exists ( PathNode out | subpaths ( _, _, n , out ) | directReach ( out ) or retReach ( out ) )
3476+ exists ( PathNodeImpl out | subpaths ( _, _, n , out ) | directReach ( out ) or retReach ( out ) )
34643477 or
34653478 exists ( PathNodeImpl mid |
34663479 retReach ( mid ) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
34773490 * sinks.
34783491 */
34793492private predicate flowsTo (
3480- PathNode flowsource , PathNodeSink flowsink , Node source , Node sink , Configuration configuration
3493+ PathNodeImpl flowsource , PathNodeSink flowsink , Node source , Node sink ,
3494+ Configuration configuration
34813495) {
34823496 flowsource .isSource ( ) and
34833497 flowsource .getConfiguration ( ) = configuration and
3484- flowsource .( PathNodeImpl ) . getNodeEx ( ) .asNode ( ) = source and
3498+ flowsource .getNodeEx ( ) .asNode ( ) = source and
34853499 ( flowsource = flowsink or pathSuccPlus ( flowsource , flowsink ) ) and
34863500 flowsink .getNodeEx ( ) .asNode ( ) = sink
34873501}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
35043518 fields = count ( TypedContent f0 | exists ( PathNodeMid pn | pn .getAp ( ) .getHead ( ) = f0 ) ) and
35053519 conscand = count ( AccessPath ap | exists ( PathNodeMid pn | pn .getAp ( ) = ap ) ) and
35063520 states = count ( FlowState state | exists ( PathNodeMid pn | pn .getState ( ) = state ) ) and
3507- tuples = count ( PathNode pn )
3521+ tuples = count ( PathNodeImpl pn )
35083522 or
35093523 fwd = false and
35103524 nodes = count ( NodeEx n0 | exists ( PathNodeImpl pn | pn .getNodeEx ( ) = n0 and reach ( pn ) ) ) and
35113525 fields = count ( TypedContent f0 | exists ( PathNodeMid pn | pn .getAp ( ) .getHead ( ) = f0 and reach ( pn ) ) ) and
35123526 conscand = count ( AccessPath ap | exists ( PathNodeMid pn | pn .getAp ( ) = ap and reach ( pn ) ) ) and
35133527 states = count ( FlowState state | exists ( PathNodeMid pn | pn .getState ( ) = state and reach ( pn ) ) ) and
3514- tuples = count ( PathNode pn | reach ( pn ) )
3528+ tuples = count ( PathNode pn )
35153529}
35163530
35173531/**
0 commit comments