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