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  --------------------------------------------------------------------------------