Print this page
11506 smatch resync

*** 47,56 **** --- 47,57 ---- enum return_type { ret_any, ret_non_zero, ret_zero, + ret_one, ret_negative, ret_positive, }; #define RETURN_VAL -1
*** 149,170 **** {"_spin_lock_bh", LOCK, "spin_lock", 0, ret_any}, {"_spin_unlock_bh", UNLOCK, "spin_lock", 0, ret_any}, {"__spin_lock_bh", LOCK, "spin_lock", 0, ret_any}, {"__spin_unlock_bh", UNLOCK, "spin_lock", 0, ret_any}, ! {"spin_trylock", LOCK, "spin_lock", 0, ret_non_zero}, ! {"_spin_trylock", LOCK, "spin_lock", 0, ret_non_zero}, ! {"__spin_trylock", LOCK, "spin_lock", 0, ret_non_zero}, ! {"raw_spin_trylock", LOCK, "spin_lock", 0, ret_non_zero}, ! {"_raw_spin_trylock", LOCK, "spin_lock", 0, ret_non_zero}, ! {"spin_trylock_irq", LOCK, "spin_lock", 0, ret_non_zero}, ! {"spin_trylock_irqsave", LOCK, "spin_lock", 0, ret_non_zero}, ! {"spin_trylock_bh", LOCK, "spin_lock", 0, ret_non_zero}, ! {"_spin_trylock_bh", LOCK, "spin_lock", 0, ret_non_zero}, ! {"__spin_trylock_bh", LOCK, "spin_lock", 0, ret_non_zero}, ! {"__raw_spin_trylock", LOCK, "spin_lock", 0, ret_non_zero}, ! {"_atomic_dec_and_lock", LOCK, "spin_lock", 1, ret_non_zero}, {"read_lock", LOCK, "read_lock", 0, ret_any}, {"read_unlock", UNLOCK, "read_lock", 0, ret_any}, {"_read_lock", LOCK, "read_lock", 0, ret_any}, {"_read_unlock", UNLOCK, "read_lock", 0, ret_any}, --- 150,171 ---- {"_spin_lock_bh", LOCK, "spin_lock", 0, ret_any}, {"_spin_unlock_bh", UNLOCK, "spin_lock", 0, ret_any}, {"__spin_lock_bh", LOCK, "spin_lock", 0, ret_any}, {"__spin_unlock_bh", UNLOCK, "spin_lock", 0, ret_any}, ! {"spin_trylock", LOCK, "spin_lock", 0, ret_one}, ! {"_spin_trylock", LOCK, "spin_lock", 0, ret_one}, ! {"__spin_trylock", LOCK, "spin_lock", 0, ret_one}, ! {"raw_spin_trylock", LOCK, "spin_lock", 0, ret_one}, ! {"_raw_spin_trylock", LOCK, "spin_lock", 0, ret_one}, ! {"spin_trylock_irq", LOCK, "spin_lock", 0, ret_one}, ! {"spin_trylock_irqsave", LOCK, "spin_lock", 0, ret_one}, ! {"spin_trylock_bh", LOCK, "spin_lock", 0, ret_one}, ! {"_spin_trylock_bh", LOCK, "spin_lock", 0, ret_one}, ! {"__spin_trylock_bh", LOCK, "spin_lock", 0, ret_one}, ! {"__raw_spin_trylock", LOCK, "spin_lock", 0, ret_one}, ! {"_atomic_dec_and_lock", LOCK, "spin_lock", 1, ret_one}, {"read_lock", LOCK, "read_lock", 0, ret_any}, {"read_unlock", UNLOCK, "read_lock", 0, ret_any}, {"_read_lock", LOCK, "read_lock", 0, ret_any}, {"_read_unlock", UNLOCK, "read_lock", 0, ret_any},
*** 195,211 **** {"_raw_read_lock_bh", LOCK, "read_lock", 0, ret_any}, {"_raw_read_unlock_bh", UNLOCK, "read_lock", 0, ret_any}, {"__raw_read_lock_bh", LOCK, "read_lock", 0, ret_any}, {"__raw_read_unlock_bh", UNLOCK, "read_lock", 0, ret_any}, ! {"generic__raw_read_trylock", LOCK, "read_lock", 0, ret_non_zero}, ! {"read_trylock", LOCK, "read_lock", 0, ret_non_zero}, ! {"_read_trylock", LOCK, "read_lock", 0, ret_non_zero}, ! {"raw_read_trylock", LOCK, "read_lock", 0, ret_non_zero}, ! {"_raw_read_trylock", LOCK, "read_lock", 0, ret_non_zero}, ! {"__raw_read_trylock", LOCK, "read_lock", 0, ret_non_zero}, ! {"__read_trylock", LOCK, "read_lock", 0, ret_non_zero}, {"write_lock", LOCK, "write_lock", 0, ret_any}, {"write_unlock", UNLOCK, "write_lock", 0, ret_any}, {"_write_lock", LOCK, "write_lock", 0, ret_any}, {"_write_unlock", UNLOCK, "write_lock", 0, ret_any}, --- 196,212 ---- {"_raw_read_lock_bh", LOCK, "read_lock", 0, ret_any}, {"_raw_read_unlock_bh", UNLOCK, "read_lock", 0, ret_any}, {"__raw_read_lock_bh", LOCK, "read_lock", 0, ret_any}, {"__raw_read_unlock_bh", UNLOCK, "read_lock", 0, ret_any}, ! {"generic__raw_read_trylock", LOCK, "read_lock", 0, ret_one}, ! {"read_trylock", LOCK, "read_lock", 0, ret_one}, ! {"_read_trylock", LOCK, "read_lock", 0, ret_one}, ! {"raw_read_trylock", LOCK, "read_lock", 0, ret_one}, ! {"_raw_read_trylock", LOCK, "read_lock", 0, ret_one}, ! {"__raw_read_trylock", LOCK, "read_lock", 0, ret_one}, ! {"__read_trylock", LOCK, "read_lock", 0, ret_one}, {"write_lock", LOCK, "write_lock", 0, ret_any}, {"write_unlock", UNLOCK, "write_lock", 0, ret_any}, {"_write_lock", LOCK, "write_lock", 0, ret_any}, {"_write_unlock", UNLOCK, "write_lock", 0, ret_any},
*** 232,264 **** {"_raw_write_lock", LOCK, "write_lock", 0, ret_any}, {"__raw_write_lock", LOCK, "write_lock", 0, ret_any}, {"_raw_write_unlock", UNLOCK, "write_lock", 0, ret_any}, {"__raw_write_unlock", UNLOCK, "write_lock", 0, ret_any}, ! {"write_trylock", LOCK, "write_lock", 0, ret_non_zero}, ! {"_write_trylock", LOCK, "write_lock", 0, ret_non_zero}, ! {"raw_write_trylock", LOCK, "write_lock", 0, ret_non_zero}, ! {"_raw_write_trylock", LOCK, "write_lock", 0, ret_non_zero}, ! {"__write_trylock", LOCK, "write_lock", 0, ret_non_zero}, ! {"__raw_write_trylock", LOCK, "write_lock", 0, ret_non_zero}, {"down", LOCK, "sem", 0, ret_any}, {"up", UNLOCK, "sem", 0, ret_any}, {"down_trylock", LOCK, "sem", 0, ret_zero}, {"down_timeout", LOCK, "sem", 0, ret_zero}, {"down_interruptible", LOCK, "sem", 0, ret_zero}, {"mutex_lock", LOCK, "mutex", 0, ret_any}, {"mutex_unlock", UNLOCK, "mutex", 0, ret_any}, {"mutex_lock_nested", LOCK, "mutex", 0, ret_any}, {"mutex_lock_interruptible", LOCK, "mutex", 0, ret_zero}, {"mutex_lock_interruptible_nested", LOCK, "mutex", 0, ret_zero}, {"mutex_lock_killable", LOCK, "mutex", 0, ret_zero}, {"mutex_lock_killable_nested", LOCK, "mutex", 0, ret_zero}, ! {"mutex_trylock", LOCK, "mutex", 0, ret_non_zero}, {"raw_local_irq_disable", LOCK, "irq", NO_ARG, ret_any}, {"raw_local_irq_enable", UNLOCK, "irq", NO_ARG, ret_any}, {"spin_lock_irq", LOCK, "irq", NO_ARG, ret_any}, {"spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any}, --- 233,279 ---- {"_raw_write_lock", LOCK, "write_lock", 0, ret_any}, {"__raw_write_lock", LOCK, "write_lock", 0, ret_any}, {"_raw_write_unlock", UNLOCK, "write_lock", 0, ret_any}, {"__raw_write_unlock", UNLOCK, "write_lock", 0, ret_any}, ! {"write_trylock", LOCK, "write_lock", 0, ret_one}, ! {"_write_trylock", LOCK, "write_lock", 0, ret_one}, ! {"raw_write_trylock", LOCK, "write_lock", 0, ret_one}, ! {"_raw_write_trylock", LOCK, "write_lock", 0, ret_one}, ! {"__write_trylock", LOCK, "write_lock", 0, ret_one}, ! {"__raw_write_trylock", LOCK, "write_lock", 0, ret_one}, {"down", LOCK, "sem", 0, ret_any}, {"up", UNLOCK, "sem", 0, ret_any}, {"down_trylock", LOCK, "sem", 0, ret_zero}, {"down_timeout", LOCK, "sem", 0, ret_zero}, {"down_interruptible", LOCK, "sem", 0, ret_zero}, + + {"down_write", LOCK, "rw_sem", 0, ret_any}, + {"downgrade_write", UNLOCK, "rw_sem", 0, ret_any}, + {"downgrade_write", LOCK, "read_sem", 0, ret_any}, + {"up_write", UNLOCK, "rw_sem", 0, ret_any}, + {"down_write_trylock", LOCK, "rw_sem", 0, ret_one}, + {"down_write_killable", LOCK, "rw_sem", 0, ret_zero}, + {"down_read", LOCK, "read_sem", 0, ret_any}, + {"down_read_trylock", LOCK, "read_sem", 0, ret_one}, + {"down_read_killable", LOCK, "read_sem", 0, ret_zero}, + {"up_read", UNLOCK, "read_sem", 0, ret_any}, + {"mutex_lock", LOCK, "mutex", 0, ret_any}, + {"mutex_lock_io", LOCK, "mutex", 0, ret_any}, {"mutex_unlock", UNLOCK, "mutex", 0, ret_any}, {"mutex_lock_nested", LOCK, "mutex", 0, ret_any}, + {"mutex_lock_io_nested", LOCK, "mutex", 0, ret_any}, {"mutex_lock_interruptible", LOCK, "mutex", 0, ret_zero}, {"mutex_lock_interruptible_nested", LOCK, "mutex", 0, ret_zero}, {"mutex_lock_killable", LOCK, "mutex", 0, ret_zero}, {"mutex_lock_killable_nested", LOCK, "mutex", 0, ret_zero}, ! {"mutex_trylock", LOCK, "mutex", 0, ret_one}, {"raw_local_irq_disable", LOCK, "irq", NO_ARG, ret_any}, {"raw_local_irq_enable", UNLOCK, "irq", NO_ARG, ret_any}, {"spin_lock_irq", LOCK, "irq", NO_ARG, ret_any}, {"spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
*** 267,277 **** {"__spin_lock_irq", LOCK, "irq", NO_ARG, ret_any}, {"__spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any}, {"_raw_spin_lock_irq", LOCK, "irq", NO_ARG, ret_any}, {"_raw_spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any}, {"__raw_spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any}, ! {"spin_trylock_irq", LOCK, "irq", NO_ARG, ret_non_zero}, {"read_lock_irq", LOCK, "irq", NO_ARG, ret_any}, {"read_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any}, {"_read_lock_irq", LOCK, "irq", NO_ARG, ret_any}, {"_read_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any}, {"__read_lock_irq", LOCK, "irq", NO_ARG, ret_any}, --- 282,292 ---- {"__spin_lock_irq", LOCK, "irq", NO_ARG, ret_any}, {"__spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any}, {"_raw_spin_lock_irq", LOCK, "irq", NO_ARG, ret_any}, {"_raw_spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any}, {"__raw_spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any}, ! {"spin_trylock_irq", LOCK, "irq", NO_ARG, ret_one}, {"read_lock_irq", LOCK, "irq", NO_ARG, ret_any}, {"read_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any}, {"_read_lock_irq", LOCK, "irq", NO_ARG, ret_any}, {"_read_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any}, {"__read_lock_irq", LOCK, "irq", NO_ARG, ret_any},
*** 302,312 **** {"_raw_spin_lock_irqsave", LOCK, "irqsave", 1, ret_any}, {"_raw_spin_unlock_irqrestore",UNLOCK, "irqsave", 1, ret_any}, {"__raw_spin_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any}, {"__raw_spin_unlock_irqrestore",UNLOCK, "irqsave", 1, ret_any}, {"_raw_spin_lock_irqsave_nested", LOCK, "irqsave", RETURN_VAL, ret_any}, ! {"spin_trylock_irqsave", LOCK, "irqsave", 1, ret_non_zero}, {"read_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any}, {"read_lock_irqsave", LOCK, "irqsave", 1, ret_any}, {"read_unlock_irqrestore", UNLOCK, "irqsave", 1, ret_any}, {"_read_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any}, {"_read_lock_irqsave", LOCK, "irqsave", 1, ret_any}, --- 317,327 ---- {"_raw_spin_lock_irqsave", LOCK, "irqsave", 1, ret_any}, {"_raw_spin_unlock_irqrestore",UNLOCK, "irqsave", 1, ret_any}, {"__raw_spin_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any}, {"__raw_spin_unlock_irqrestore",UNLOCK, "irqsave", 1, ret_any}, {"_raw_spin_lock_irqsave_nested", LOCK, "irqsave", RETURN_VAL, ret_any}, ! {"spin_trylock_irqsave", LOCK, "irqsave", 1, ret_one}, {"read_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any}, {"read_lock_irqsave", LOCK, "irqsave", 1, ret_any}, {"read_unlock_irqrestore", UNLOCK, "irqsave", 1, ret_any}, {"_read_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any}, {"_read_lock_irqsave", LOCK, "irqsave", 1, ret_any},
*** 346,358 **** {"write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any}, {"_write_lock_bh", LOCK, "bottom_half", NO_ARG, ret_any}, {"_write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any}, {"__write_lock_bh", LOCK, "bottom_half", NO_ARG, ret_any}, {"__write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any}, ! {"spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_non_zero}, ! {"_spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_non_zero}, ! {"__spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_non_zero}, {"ffs_mutex_lock", LOCK, "mutex", 0, ret_zero}, }; static struct lock_info *lock_table; --- 361,373 ---- {"write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any}, {"_write_lock_bh", LOCK, "bottom_half", NO_ARG, ret_any}, {"_write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any}, {"__write_lock_bh", LOCK, "bottom_half", NO_ARG, ret_any}, {"__write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any}, ! {"spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_one}, ! {"_spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_one}, ! {"__spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_one}, {"ffs_mutex_lock", LOCK, "mutex", 0, ret_zero}, }; static struct lock_info *lock_table;
*** 445,454 **** --- 460,478 ---- { if (is_impossible_path()) set_state(my_id, sm->name, sm->sym, &impossible); } + static bool nestable(const char *name) + { + if (strstr(name, "read_sem:")) + return true; + if (strcmp(name, "bottom_half:") == 0) + return true; + return false; + } + static void do_lock(const char *name) { struct sm_state *sm; if (__inline_fn)
*** 455,466 **** return; sm = get_sm_state(my_id, name, NULL); if (!sm) add_tracker(&starts_unlocked, my_id, name, NULL); ! if (sm && slist_has_state(sm->possible, &locked) && ! strcmp(name, "bottom_half:") != 0) sm_error("double lock '%s'", name); if (sm) func_has_transition = TRUE; set_state(my_id, name, NULL, &locked); } --- 479,489 ---- return; sm = get_sm_state(my_id, name, NULL); if (!sm) add_tracker(&starts_unlocked, my_id, name, NULL); ! if (sm && slist_has_state(sm->possible, &locked) && !nestable(name)) sm_error("double lock '%s'", name); if (sm) func_has_transition = TRUE; set_state(my_id, name, NULL, &locked); }
*** 742,757 **** --- 765,783 ---- } static int matches_return_type(struct range_list *rl, enum return_type type) { sval_t zero_sval = ll_to_sval(0); + sval_t one_sval = ll_to_sval(1); /* All these double negatives are super ugly! */ switch (type) { case ret_zero: return !possibly_true_rl(rl, SPECIAL_NOTEQUAL, alloc_rl(zero_sval, zero_sval)); + case ret_one: + return !possibly_true_rl(rl, SPECIAL_NOTEQUAL, alloc_rl(one_sval, one_sval)); case ret_non_zero: return !possibly_true_rl(rl, SPECIAL_EQUAL, alloc_rl(zero_sval, zero_sval)); case ret_negative: return !possibly_true_rl(rl, SPECIAL_GTE, alloc_rl(zero_sval, zero_sval)); case ret_positive:
*** 904,922 **** { struct lock_info *lock = &lock_table[index]; void *idx = INT_PTR(index); if (lock->return_type == ret_non_zero) { ! return_implies_state(lock->function, valid_ptr_min, valid_ptr_max, &match_lock_held, idx); return_implies_state(lock->function, 0, 0, &match_lock_failed, idx); } else if (lock->return_type == ret_any && lock->arg == RETURN_VAL) { add_function_assign_hook(lock->function, &match_returns_locked, idx); } else if (lock->return_type == ret_any) { add_function_hook(lock->function, &match_lock_unlock, idx); } else if (lock->return_type == ret_zero) { return_implies_state(lock->function, 0, 0, &match_lock_held, idx); return_implies_state(lock->function, -4095, -1, &match_lock_failed, idx); } } static void load_table(struct lock_info *_lock_table, int size) { --- 930,951 ---- { struct lock_info *lock = &lock_table[index]; void *idx = INT_PTR(index); if (lock->return_type == ret_non_zero) { ! return_implies_state(lock->function, 1, INT_MAX, &match_lock_held, idx); return_implies_state(lock->function, 0, 0, &match_lock_failed, idx); } else if (lock->return_type == ret_any && lock->arg == RETURN_VAL) { add_function_assign_hook(lock->function, &match_returns_locked, idx); } else if (lock->return_type == ret_any) { add_function_hook(lock->function, &match_lock_unlock, idx); } else if (lock->return_type == ret_zero) { return_implies_state(lock->function, 0, 0, &match_lock_held, idx); return_implies_state(lock->function, -4095, -1, &match_lock_failed, idx); + } else if (lock->return_type == ret_one) { + return_implies_state(lock->function, 1, 1, &match_lock_held, idx); + return_implies_state(lock->function, 0, 0, &match_lock_failed, idx); } } static void load_table(struct lock_info *_lock_table, int size) {