kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/docs/schema/influences-relation.txt (about) 1 // Copyright 2021 The Kythe Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 The `influences` relation 16 ========================= 17 18 Kythe stores information about dataflow in the graph using 19 https://kythe.io/docs/schema/#influences[`influences`] edges. A node *A* 20 influences a node *B* if *A* directly affects *B* during the evaluation 21 of a program. This relationship is not intended to model all dataflow 22 interactions. In particular, it excludes nontrivial aliasing (that can't 23 be decided within the scope of a single compilation unit). Despite this, 24 the influence relation can be used to trace simple paths through a program 25 by exploring the subgraph iteratively, allowing for non-universal queries 26 that fit the following examples: 27 28 * find places where a flag passed to a program directly affects a different 29 program value 30 * find places where the return value from a sensitive function is passed to an 31 insensitive sink, like leaking a key to a logging function 32 * identify the places that affect a program value that was assigned something 33 unexpected at runtime 34 35 This document is intended to describe how to add the `influences` relationship 36 to a Kythe indexer based on common language features. Note that this document 37 is still under active development. 38 39 == General framework 40 41 We assume that the indexer being amended performs an AST walk over a tree 42 with resolved references (so it's possible to construct VNames for, e.g., 43 a variable that is referenced). The indexer should maintain a stack of 44 sets of influencers (using whichever type is appopriate; for C++, we use 45 pointers to declarations). As the indexer enters and leaves various kinds of 46 AST node and encounters others, it will manipulate this stack. 47 48 Names follow this convention: 49 50 * `v` is a simple program variable. 51 * `p` is a parameter. 52 * `e` is an expression. 53 54 Popping the set "onto" an object `o` with node `n` means removing the top 55 set from the influencers stack and recording `i influences n` edges for all 56 nodes `i` for the objects in that top set. 57 58 The *blame context* is the node or nodes that would be assigned responsibility 59 for making a function call at the current point in the AST. For example: 60 61 int f() { g(); } 62 63 Here, the call to `g` would be assigned to blame context `f`. 64 65 == Variables 66 67 === Simple reference 68 69 v 70 71 * Insert `v`. 72 73 === Simple assignment 74 75 v := e 76 77 * Push `{}`. 78 * Traverse `e`. 79 * Pop onto `v`. 80 81 [kythe,C++,"A simple expression.",0] 82 -------------------------------------------------------------------------------- 83 void f() { 84 //- @x defines/binding VarX 85 int x = 0; 86 //- @y defines/binding VarY 87 int y = 1; 88 //- // VarX influences VarY 89 y = x; 90 } 91 -------------------------------------------------------------------------------- 92 93 == Functions 94 95 === Simple calls 96 97 e(e1 ... eN) 98 99 * Traverse `e`. 100 * For each of `e1 ... eN` with corresponding parameters `p1 ... pN`: 101 * Push `{}`. 102 * Traverse `eI`. 103 * Pop onto `pI`. 104 * Insert `e`. 105 106 === Returns 107 108 return e; 109 110 * Push `{}`. 111 * Traverse `e`. 112 * Pop onto the blame context. 113 114 [kythe,C++,"A function call.",0] 115 -------------------------------------------------------------------------------- 116 //- @x defines/binding ParamX 117 //- @g defines/binding FnG 118 int g(int x) { 119 //- ParamX influences FnG 120 return x + 1; 121 } 122 123 void f() { 124 //- @y defines/binding VarY 125 int y = 0; 126 //- @z defines/binding VarZ 127 int z; 128 //- VarY influences ParamX 129 //- FnG influences VarZ 130 z = y + g(y); 131 } 132 -------------------------------------------------------------------------------- 133 134 === Forward declarations 135 136 f'(p'1 ... p'N); 137 f(p1 ... pN) { ... } 138 139 * `p'I` influences `pI`. 140 * `f` influences `f'`. 141 142 [kythe,C++,"Forward declarations.",0] 143 -------------------------------------------------------------------------------- 144 //- @f defines/binding FwdFnF 145 //- @x defines/binding FwdParamX 146 //- @y defines/binding FwdParamY 147 int f(int x, int y); 148 149 //- @f defines/binding DefnFnF 150 //- @x defines/binding DefnParamX 151 //- @y defines/binding DefnParamY 152 int f(int x, int y) { 153 return x + y; 154 } 155 156 //- FwdParamX influences DefnParamX 157 //- FwdParamY influences DefnParamY 158 //- DefnFnF influences FwdFnF 159 --------------------------------------------------------------------------------