1 /*
   2  * Copyright (C) 2014 Oracle.
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License
   6  * as published by the Free Software Foundation; either version 2
   7  * of the License, or (at your option) any later version.
   8  *
   9  * This program is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  * GNU General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU General Public License
  15  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
  16  */
  17 
  18 /*
  19  * The plan here is to save all the possible values store to a given struct
  20  * member.
  21  *
  22  * We will load all the values in to the function_type_val table first then
  23  * run a script on that and load all the resulting values into the type_val
  24  * table.
  25  *
  26  * So in this file we want to take the union of everything assigned to the
  27  * struct member and insert it into the function_type_val at the end.
  28  *
  29  * You would think that we could use smatch_modification_hooks.c or
  30  * extra_modification_hook() here to get the information here but in the end we
  31  * need to code everything again a third time.
  32  *
  33  */
  34 
  35 /*
  36  * Remember links like:
  37  *
  38  * foo->void_ptr = some_struct.
  39  *
  40  * If we get a some_struct pointer from foo->void_ptr then assume it's the same
  41  * stuff.
  42  */
  43 
  44 #include "smatch.h"
  45 #include "smatch_slist.h"
  46 #include "smatch_extra.h"
  47 
  48 static int my_id;
  49 
  50 static void match_assign(struct expression *expr)
  51 {
  52         struct symbol *type;
  53 
  54         if (!is_void_pointer(expr->left))
  55                 return;
  56 
  57         type = get_type(expr->right);
  58         if (!type || type->type != SYM_PTR)
  59                 return;
  60         type = get_real_base_type(type);
  61         if (!type || type->type != SYM_STRUCT)
  62                 return;
  63 
  64         sql_insert_data_info(expr->left, TYPE_LINK, type_to_str(type));
  65 }
  66 
  67 void register_type_links(int id)
  68 {
  69         if (!option_info)
  70                 return;
  71         my_id = id;
  72 
  73         add_hook(&match_assign, ASSIGNMENT_HOOK);
  74 }