Exemple #1
0
static void match_loop(struct statement *stmt)
{
	struct expression *iterator;
	char *iter_set;
	char *iter_tested;

	if (get_macro_name(stmt->pos))
		return;

	iterator = get_iterator_set(stmt->iterator_pre_statement);
	iter_set = expr_to_var(iterator);
	iterator = get_iterator_tested(stmt->iterator_pre_condition);
	iter_tested = expr_to_var(iterator);
	if (!iter_set || !iter_tested)
		goto free;
	if (strcmp(iter_set, iter_tested))
		goto free;

	/* smatch doesn't handle loops correctly so this silences some
	 * false positives.
	 */
	if (right_side_changes(stmt->iterator_pre_condition))
		goto free;

	if (implied_condition_false(stmt->iterator_pre_condition))
		sm_msg("warn: we never enter this loop");

free:
	free_string(iter_set);
	free_string(iter_tested);
}
static void match_return(struct expression *ret_value)
{
	struct expression *expr;
	char *macro;

	if (!ret_value)
		return;
	expr = ret_value;
	if (ret_value->type != EXPR_PREOP || ret_value->op != '-')
		return;

	macro = get_macro_name(expr->unop->pos);
	if (macro && !strcmp(macro, "PTR_ERR")) {
		sm_msg("warn: returning -%s()", macro);
		return;
	}

	if (!option_spammy)
		return;

	expr = get_assigned_expr(ret_value->unop);
	if (!expr)
		return;
	if (expr->type != EXPR_CALL)
		return;

	sm_msg("warn: should this return really be negated?");
}
Exemple #3
0
static void match_call_assignment(struct expression *expr)
{
	if (get_macro_name(expr->left->pos))
		return;
	last_return = expr->left;
	last_func = expr->right;
}
Exemple #4
0
static int is_unconstant_macro(struct expression *expr)
{
	char *macro;

	macro = get_macro_name(expr->pos);
	if (!macro)
		return 0;
	if (search_unconstant_macros(unconstant_macros, macro))
		return 1;
	return 0;
}
Exemple #5
0
static void match_binop(struct expression *expr)
{
	sval_t left, right, sval;

	if (expr->op != '&')
		return;
	if (!get_value(expr, &sval) || sval.value != 0)
		return;
	if (get_macro_name(expr->pos))
		return;
	if (!get_value(expr->left, &left) || !get_value(expr->right, &right))
		return;
	sm_msg("warn: odd binop '0x%llx & 0x%llx'", left.uvalue, right.uvalue);
}
Exemple #6
0
static void match_inside(struct expression *expr, struct position pos)
{
	char *name;
	int matched = 0;

	if (positions_eq(expr->pos, pos))
		matched++;
	if (positions_eq(expr->unop->pos, pos))
		matched++;
	if (matched != 1)
		return;
	name = get_macro_name(pos);
	if (!name)
		return;
	sm_msg("warn: the '%s' macro might need parens", name);
}
static void match_assign(struct expression *expr)
{
	char *name;

	name = get_macro_name(expr->pos);
	if (!name || strcmp(name, "get_user") != 0) {
		match_normal_assign(expr);
		return;
	}
	name = expr_to_var(expr->right);
	if (!name || strcmp(name, "__val_gu") != 0)
		goto free;
	set_state_expr(my_max_id, expr->left, &user_data);
	set_state_expr(my_min_id, expr->left, &user_data);
free:
	free_string(name);
}
static void match_condition(struct expression *expr)
{
	struct symbol *type;
	char *str;

	if (expr->type != EXPR_DEREF)
		return;
	type = get_type(expr);
	if (!type || type->type != SYM_ARRAY)
		return;
	if (get_macro_name(expr->pos))
		return;

	str = expr_to_str(expr);
	sm_msg("warn: this array is probably non-NULL. '%s'", str);
	free_string(str);
}
Exemple #9
0
static void match_one_side(struct expression *expr, struct position pos, int op)
{
	char *name;
	int matched = 0;

	if ((op == '+' || op == '*' || op == '|' || op == '&') && expr->op == op)
		return;
	if (positions_eq(expr->right->pos, pos))
		matched++;
	if (positions_eq(expr->left->pos, pos))
		matched++;
	if (matched != 1)
		return;
	name = get_macro_name(pos);
	if (!name)
		return;
	if (option_project == PROJ_WINE && !strcmp("BEGIN", name))
		return;
	sm_msg("warn: the '%s' macro might need parens", name);
}
Exemple #10
0
static void match_condition(struct expression *expr)
{
	sval_t sval;

	if (expr->type != EXPR_BINOP)
		return;
	if (expr->op == '|') {
		if (get_value(expr->left, &sval) || get_value(expr->right, &sval))
			sm_msg("warn: suspicious bitop condition");
		return;
	}

	if (expr->op != '&')
		return;

	if (get_macro_name(expr->pos))
		return;
	if (is_unconstant_macro(expr->left) || is_unconstant_macro(expr->right))
		return;

	if ((get_value(expr->left, &sval) && sval.value == 0) ||
	    (get_value(expr->right, &sval) && sval.value == 0))
		sm_msg("warn: bitwise AND condition is false here");
}
Exemple #11
0
char *part_property_expand_macros (Part *part, char *string)
{
	static char mcode[] = {"@?~#&"};
	char *value;
	char *tmp0, *temp, *qn, *q0, *t0;
	char *cls1, *cls2;
	GString *out;
	size_t sln;
	char *ret;

	g_return_val_if_fail (part != NULL, NULL);
	g_return_val_if_fail (IS_PART (part), NULL);
	g_return_val_if_fail (string != NULL, NULL);

	cls1 = cls2 = q0 = NULL;
	// Rules:
	// @<id>             value of <id>. If no value, error
	// &<id>             value of <id> if <id> is defined
	// ?<id>s...s        text between s...s separators if <id> defined
	// ?<id>s...ss...s   text between 1st s...s separators if <id> defined
	// else 2nd s...s clause
	// ~<id>s...s        text between s...s separators if <id> undefined
	// ~<id>s...ss...s   text between 1st s...s separators if <id> undefined
	// else 2nd s...s clause
	// #<id>s...s        text between s...s separators if <id> defined, but
	// delete rest of tempalte if <id> undefined

	// Separators can be any of (, . ; / |) For an opening-closing pair of
	// separators the same character ahs to be used.

	// Examples: R^@refdes %1 %2 @value
	// V^@refdes %+ %- SIN(@offset @ampl @freq 0 0)
	// ?DC|DC @DC|

	tmp0 = temp = g_strdup (string);

	out = g_string_new ("");

	for (temp = string; *temp;) {
		// Look for any of the macro char codes.
		if (strchr (mcode, *temp)) {
			qn = get_macro_name (temp + 1, &cls1, &cls2, &sln);
			if (qn == NULL)
				return NULL;
			value = part_get_property (part, qn);
			if ((*temp == '@' || *temp == '&') && value) {
				out = g_string_append (out, value);
			} else if (*temp == '&' && !value) {
				g_warning ("expand macro error: macro %s undefined", qn);
				g_free (qn);
				return NULL;
			} else if (*temp == '?' || *temp == '~') {
				if (cls1 == NULL) {
					g_warning ("error in template: %s", temp);
					g_free (qn);
					return NULL;
				}
				q0 = (value ? (*temp == '?' ? cls1 : cls2) : (*temp == '?' ? cls2 : cls1));
				if (q0) {
					t0 = part_property_expand_macros (part, q0);
					if (!t0) {
						g_warning ("error in template: %s", temp);
						g_free (qn);
					} else {
						out = g_string_append (out, t0);
						g_free (t0);
					}
				}
			} else if (*temp == '#') {
				if (value) {
					t0 = part_property_expand_macros (part, value);
					if (!t0) {
						g_warning ("error in template: %s", temp);
						g_free (qn);
					} else {
						out = g_string_append (out, t0);
						g_free (t0);
					}
				} else
					*(temp + sln) = 0;
			}
			temp += 1;
			temp += sln;
			if (qn)
				g_free (qn);
			if (cls1)
				g_free (cls1);
			if (cls2)
				g_free (cls2);
		} else {
			if (*temp == '\\') {
				temp++;
				switch (*temp) {
				case 'n':
					out = g_string_append_c (out, '\n');
					break;
				case 't':
					out = g_string_append_c (out, '\t');
					break;
				case 'r':
					out = g_string_append_c (out, '\r');
					break;
				case 'f':
					out = g_string_append_c (out, '\f');
				}
				temp++;
			} else {
				out = g_string_append_c (out, *temp);
				temp++;
			}
		}
	}

	if (tmp0)
		g_free (tmp0);

	out = g_string_append_c (out, '\0');
	ret = g_strdup (out->str);
	g_string_free (out, TRUE);

	return ret;
}