1 /* 2 * Copyright (C) 2010 Dan Carpenter. 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 static void match_inside(struct expression *expr, struct position pos) 23 { 24 char *name; 25 int matched = 0; 26 27 if (positions_eq(expr->pos, pos)) 28 matched++; 29 if (positions_eq(expr->unop->pos, pos)) 30 matched++; 31 if (matched != 1) 32 return; 33 name = get_macro_name(pos); 34 if (!name) 35 return; 36 sm_warning("the '%s' macro might need parens", name); 37 } 38 39 static void match_one_side(struct expression *expr, struct position pos, int op) 40 { 41 char *name; 42 int matched = 0; 43 44 if ((op == '+' || op == '*' || op == '|' || op == '&') && expr->op == op) 45 return; 46 if (positions_eq(expr->right->pos, pos)) 47 matched++; 48 if (positions_eq(expr->left->pos, pos)) 49 matched++; 50 if (matched != 1) 51 return; 52 name = get_macro_name(pos); 53 if (!name) 54 return; 55 if (option_project == PROJ_WINE && !strcmp("BEGIN", name)) 56 return; 57 sm_warning("the '%s' macro might need parens", name); 58 } 59 60 static void match_join(struct expression *expr) 61 { 62 if (expr->left->type == EXPR_PREOP) 63 match_inside(expr->left, expr->pos); 64 if (expr->right->type == EXPR_POSTOP) 65 match_inside(expr->right, expr->pos); 66 67 if (expr->left->type == EXPR_BINOP) 68 match_one_side(expr->left, expr->pos, expr->op); 69 if (expr->right->type == EXPR_BINOP) 70 match_one_side(expr->right, expr->pos, expr->op); 71 } 72 73 void check_macros(int id) 74 { 75 my_id = id; 76 add_hook(&match_join, BINOP_HOOK); 77 add_hook(&match_join, LOGIC_HOOK); 78 } 79