1 /*
   2  * Copyright (C) 2012 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 #include "smatch.h"
  19 
  20 static int my_id;
  21 
  22 #if 0
  23 static unsigned long long find_possible_bits(struct expression *expr)
  24 {
  25         sval_t sval;
  26         unsigned long long ret;
  27         int set;
  28         int i;
  29 
  30         expr = strip_expr(expr);
  31 
  32         if (get_implied_value(expr, &sval))
  33                 return sval.uvalue;
  34 
  35         if (expr->type == EXPR_BINOP && (expr->op == '&' || expr->op == '|')) {
  36                 unsigned long long left, right;
  37 
  38                 left = find_possible_bits(expr->left);
  39                 if (!left)
  40                         return 0;
  41                 right = find_possible_bits(expr->right);
  42                 if (!right)
  43                         return 0;
  44 
  45                 if (expr->op == '&')
  46                         return left & right;
  47                 return left | right;
  48         }
  49 
  50         get_absolute_max(expr, &sval);
  51         ret = sval.value;
  52 
  53         set = false;
  54         for (i = 63; i >= 0; i--) {
  55                 if (ret & 1 << i)
  56                         set = true;
  57                 if (set)
  58                         ret |= 1 << i;
  59         }
  60         return ret;
  61 }
  62 #endif
  63 
  64 static unsigned long long get_possible_bits(struct expression *expr)
  65 {
  66         sval_t sval;
  67 
  68         expr = strip_expr(expr);
  69         if (expr->type != EXPR_BINOP)
  70                 return 0;
  71         if (expr->op != '&')
  72                 return 0;
  73         if (!get_implied_value(expr->right, &sval))
  74                 return 0;
  75 
  76         return sval.uvalue;
  77 }
  78 
  79 static void match_condition(struct expression *expr)
  80 {
  81         struct symbol *type;
  82         sval_t sval;
  83         unsigned long long left_mask, right_mask;
  84         char *str;
  85 
  86         type = get_type(expr);
  87         if (!type)
  88                 type = &int_ctype;
  89 
  90         if (expr->type != EXPR_COMPARE)
  91                 return;
  92         if (expr->op != SPECIAL_EQUAL && expr->op != SPECIAL_NOTEQUAL)
  93                 return;
  94 
  95         if (!get_value(expr->right, &sval))
  96                 return;
  97         right_mask = sval.uvalue;
  98 
  99         left_mask = get_possible_bits(expr->left);
 100         if (!left_mask)
 101                 return;
 102 
 103         if (type_bits(type) < 64) {
 104                 left_mask &= (1ULL << type_bits(type)) - 1;
 105                 right_mask &= (1ULL << type_bits(type)) - 1;
 106         }
 107 
 108         if ((left_mask & right_mask) == right_mask)
 109                 return;
 110 
 111         str = expr_to_str(expr);
 112         sm_warning("masked condition '%s' is always %s.", str,
 113                expr->op == SPECIAL_EQUAL ? "false" : "true");
 114         free_string(str);
 115 }
 116 
 117 void check_impossible_mask(int id)
 118 {
 119         my_id = id;
 120 
 121         add_hook(&match_condition, CONDITION_HOOK);
 122 }