Print this page
12724 update smatch to 0.6.1-rc1-il-5

@@ -145,11 +145,11 @@
                 i++;
         } END_FOR_EACH_PTR(expr);
         return NULL;
 }
 
-static struct expression *get_array_expr(struct expression *expr)
+struct expression *get_array_expr(struct expression *expr)
 {
         struct expression *parent;
         struct symbol *type;
 
         if (expr->type != EXPR_BINOP || expr->op != '+')

@@ -172,14 +172,12 @@
         return NULL;
 }
 
 static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
                                      struct expression *expr, int len,
-                                     int *complicated, int no_parens)
+                                     int *complicated)
 {
-
-
         if (!expr) {
                 /* can't happen on valid code */
                 *complicated = 1;
                 return;
         }

@@ -202,11 +200,11 @@
                                         op = '.';
                                 deref = deref->unop;
                         }
                 }
 
-                __get_variable_from_expr(sym_ptr, buf, deref, len, complicated, no_parens);
+                __get_variable_from_expr(sym_ptr, buf, deref, len, complicated);
 
                 if (op == '*')
                         append(buf, "->", len);
                 else
                         append(buf, ".", len);

@@ -234,20 +232,20 @@
                         *complicated = 2;
                         return;
                 }
 
                 if (expr->op == '(') {
-                        if (!no_parens && expr->unop->type != EXPR_SYMBOL)
+                        if (expr->unop->type != EXPR_SYMBOL)
                                 append(buf, "(", len);
                 } else if (expr->op != '*' || !get_array_expr(expr->unop)) {
                         tmp = show_special(expr->op);
                         append(buf, tmp, len);
                 }
                 __get_variable_from_expr(sym_ptr, buf, expr->unop,
-                                                 len, complicated, no_parens);
+                                                 len, complicated);
 
-                if (expr->op == '(' && !no_parens && expr->unop->type != EXPR_SYMBOL)
+                if (expr->op == '(' && expr->unop->type != EXPR_SYMBOL)
                         append(buf, ")", len);
 
                 if (expr->op == SPECIAL_DECREMENT ||
                                 expr->op == SPECIAL_INCREMENT)
                         *complicated = 1;

@@ -256,11 +254,11 @@
         }
         case EXPR_POSTOP: {
                 const char *tmp;
 
                 __get_variable_from_expr(sym_ptr, buf, expr->unop,
-                                                 len, complicated, no_parens);
+                                                 len, complicated);
                 tmp = show_special(expr->op);
                 append(buf, tmp, len);
 
                 if (expr->op == SPECIAL_DECREMENT || expr->op == SPECIAL_INCREMENT)
                         *complicated = 1;

@@ -274,18 +272,18 @@
                 struct expression *array_expr;
 
                 *complicated = 1;
                 array_expr = get_array_expr(expr);
                 if (array_expr) {
-                        __get_variable_from_expr(sym_ptr, buf, array_expr, len, complicated, no_parens);
+                        __get_variable_from_expr(sym_ptr, buf, array_expr, len, complicated);
                         append(buf, "[", len);
                 } else {
-                        __get_variable_from_expr(sym_ptr, buf, expr->left, len, complicated, no_parens);
+                        __get_variable_from_expr(sym_ptr, buf, expr->left, len, complicated);
                         snprintf(tmp, sizeof(tmp), " %s ", show_special(expr->op));
                         append(buf, tmp, len);
                 }
-                __get_variable_from_expr(NULL, buf, expr->right, len, complicated, no_parens);
+                __get_variable_from_expr(NULL, buf, expr->right, len, complicated);
                 if (array_expr)
                         append(buf, "]", len);
                 return;
         }
         case EXPR_VALUE: {

@@ -319,26 +317,26 @@
         case EXPR_CALL: {
                 struct expression *tmp;
                 int i;
 
                 *complicated = 1;
-                __get_variable_from_expr(NULL, buf, expr->fn, len, complicated, no_parens);
+                __get_variable_from_expr(NULL, buf, expr->fn, len, complicated);
                 append(buf, "(", len);
                 i = 0;
                 FOR_EACH_PTR(expr->args, tmp) {
                         if (i++)
                                 append(buf, ", ", len);
-                        __get_variable_from_expr(NULL, buf, tmp, len, complicated, no_parens);
+                        __get_variable_from_expr(NULL, buf, tmp, len, complicated);
                 } END_FOR_EACH_PTR(tmp);
                 append(buf, ")", len);
                 return;
         }
         case EXPR_CAST:
         case EXPR_FORCE_CAST:
                 __get_variable_from_expr(sym_ptr, buf,
                                          expr->cast_expression, len,
-                                         complicated, no_parens);
+                                         complicated);
                 return;
         case EXPR_SIZEOF: {
                 sval_t sval;
                 int size;
                 char tmp[25];

@@ -356,51 +354,66 @@
         case EXPR_IDENTIFIER:
                 *complicated = 1;
                 if (expr->expr_ident)
                         append(buf, expr->expr_ident->name, len);
                 return;
-        default:
+        case EXPR_SELECT:
+        case EXPR_CONDITIONAL:
                 *complicated = 1;
-                //printf("unknown type = %d\n", expr->type);
+                append(buf, "(", len);
+                __get_variable_from_expr(NULL, buf, expr->conditional, len, complicated);
+                append(buf, ") ?", len);
+                if (expr->cond_true)
+                        __get_variable_from_expr(NULL, buf, expr->cond_true, len, complicated);
+                append(buf, ":", len);
+                __get_variable_from_expr(NULL, buf, expr->cond_false, len, complicated);
                 return;
+        default: {
+                        char tmp[64];
+
+                        snprintf(tmp, sizeof(tmp), "$expr_%p(%d)", expr, expr->type);
+                        append(buf, tmp, len);
+                        *complicated = 1;
         }
+                return;
+        }
 }
 
 struct expr_str_cache_results {
         struct expression *expr;
-        int no_parens;
         char str[VAR_LEN];
         struct symbol *sym;
         int complicated;
 };
 
 static void get_variable_from_expr(struct symbol **sym_ptr, char *buf,
                                      struct expression *expr, int len,
-                                     int *complicated, int no_parens)
+                                     int *complicated)
 {
         static struct expr_str_cache_results cached[8];
         struct symbol *tmp_sym = NULL;
         static int idx;
         int i;
 
         for (i = 0; i < ARRAY_SIZE(cached); i++) {
-                if (expr == cached[i].expr &&
-                    no_parens == cached[i].no_parens) {
+                if (expr == cached[i].expr) {
                         strncpy(buf, cached[i].str, len);
                         if (sym_ptr)
                                 *sym_ptr = cached[i].sym;
                         *complicated = cached[i].complicated;
                         return;
                 }
         }
 
-        __get_variable_from_expr(&tmp_sym, buf, expr, len, complicated, no_parens);
+        __get_variable_from_expr(&tmp_sym, buf, expr, len, complicated);
         if (sym_ptr)
                 *sym_ptr = tmp_sym;
 
+        if (expr->smatch_flags & Tmp)
+                return;
+
         cached[idx].expr = expr;
-        cached[idx].no_parens = no_parens;
         strncpy(cached[idx].str, buf, VAR_LEN);
         cached[idx].sym = tmp_sym;
         cached[idx].complicated = *complicated;
 
         idx = (idx + 1) % ARRAY_SIZE(cached);

@@ -425,11 +438,11 @@
         var_name[0] = '\0';
 
         if (!expr)
                 return NULL;
         get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
-                                 &complicated, 0);
+                               &complicated);
         if (complicated < 2)
                 return alloc_string(var_name);
         else
                 return NULL;
 }

@@ -456,11 +469,11 @@
 
         if (!expr)
                 return NULL;
         expr = strip_expr(expr);
         get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
-                                 &complicated, 1);
+                               &complicated);
 
         if (complicated) {
                 if (sym_ptr)
                         *sym_ptr = NULL;
                 return NULL;

@@ -1049,33 +1062,48 @@
 int get_param_num_from_sym(struct symbol *sym)
 {
         struct symbol *tmp;
         int i;
 
-        if (!cur_func_sym)
-                return -1;
+        if (!sym)
+                return UNKNOWN_SCOPE;
 
+        if (sym->ctype.modifiers & MOD_TOPLEVEL) {
+                if (sym->ctype.modifiers & MOD_STATIC)
+                        return FILE_SCOPE;
+                return GLOBAL_SCOPE;
+        }
+
+        if (!cur_func_sym) {
+                if (!parse_error) {
+                        sm_msg("warn: internal.  problem with scope:  %s",
+                               sym->ident ? sym->ident->name : "<anon var>");
+                }
+                return GLOBAL_SCOPE;
+        }
+
+
         i = 0;
         FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, tmp) {
                 if (tmp == sym)
                         return i;
                 i++;
         } END_FOR_EACH_PTR(tmp);
-        return -1;
+        return LOCAL_SCOPE;
 }
 
 int get_param_num(struct expression *expr)
 {
         struct symbol *sym;
         char *name;
 
         if (!cur_func_sym)
-                return -1;
+                return UNKNOWN_SCOPE;
         name = expr_to_var_sym(expr, &sym);
         free_string(name);
         if (!sym)
-                return -1;
+                return UNKNOWN_SCOPE;
         return get_param_num_from_sym(sym);
 }
 
 struct symbol *get_param_sym_from_num(int num)
 {