11f5207b7SJohn Levon /*
21f5207b7SJohn Levon  * Copyright (C) 2010 Dan Carpenter.
31f5207b7SJohn Levon  *
41f5207b7SJohn Levon  * This program is free software; you can redistribute it and/or
51f5207b7SJohn Levon  * modify it under the terms of the GNU General Public License
61f5207b7SJohn Levon  * as published by the Free Software Foundation; either version 2
71f5207b7SJohn Levon  * of the License, or (at your option) any later version.
81f5207b7SJohn Levon  *
91f5207b7SJohn Levon  * This program is distributed in the hope that it will be useful,
101f5207b7SJohn Levon  * but WITHOUT ANY WARRANTY; without even the implied warranty of
111f5207b7SJohn Levon  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
121f5207b7SJohn Levon  * GNU General Public License for more details.
131f5207b7SJohn Levon  *
141f5207b7SJohn Levon  * You should have received a copy of the GNU General Public License
151f5207b7SJohn Levon  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
161f5207b7SJohn Levon  */
171f5207b7SJohn Levon 
181f5207b7SJohn Levon /*
191f5207b7SJohn Levon  * smatch_dinfo.c has helper functions for handling data_info structs
201f5207b7SJohn Levon  *
211f5207b7SJohn Levon  */
221f5207b7SJohn Levon 
231f5207b7SJohn Levon #include <stdlib.h>
241f5207b7SJohn Levon #ifndef __USE_ISOC99
251f5207b7SJohn Levon #define __USE_ISOC99
261f5207b7SJohn Levon #endif
271f5207b7SJohn Levon #include <limits.h>
281f5207b7SJohn Levon #include "parse.h"
291f5207b7SJohn Levon #include "smatch.h"
301f5207b7SJohn Levon #include "smatch_slist.h"
311f5207b7SJohn Levon #include "smatch_extra.h"
321f5207b7SJohn Levon 
merge_estates(struct smatch_state * s1,struct smatch_state * s2)331f5207b7SJohn Levon struct smatch_state *merge_estates(struct smatch_state *s1, struct smatch_state *s2)
341f5207b7SJohn Levon {
351f5207b7SJohn Levon 	struct smatch_state *tmp;
361f5207b7SJohn Levon 	struct range_list *value_ranges;
371f5207b7SJohn Levon 	struct related_list *rlist;
381f5207b7SJohn Levon 
391f5207b7SJohn Levon 	if (estates_equiv(s1, s2))
401f5207b7SJohn Levon 		return s1;
411f5207b7SJohn Levon 
421f5207b7SJohn Levon 	value_ranges = rl_union(estate_rl(s1), estate_rl(s2));
431f5207b7SJohn Levon 	tmp = alloc_estate_rl(value_ranges);
441f5207b7SJohn Levon 	rlist = get_shared_relations(estate_related(s1), estate_related(s2));
451f5207b7SJohn Levon 	set_related(tmp, rlist);
46efe51d0cSJohn Levon 
47efe51d0cSJohn Levon 	if ((estate_has_hard_max(s1) && (!estate_rl(s2) || estate_has_hard_max(s2))) ||
48efe51d0cSJohn Levon 	    (estate_has_hard_max(s2) && (!estate_rl(s1) || estate_has_hard_max(s1))))
491f5207b7SJohn Levon 		estate_set_hard_max(tmp);
501f5207b7SJohn Levon 
511f5207b7SJohn Levon 	estate_set_fuzzy_max(tmp, sval_max(estate_get_fuzzy_max(s1), estate_get_fuzzy_max(s2)));
521f5207b7SJohn Levon 
53efe51d0cSJohn Levon 	if (estate_capped(s1) && estate_capped(s2))
54efe51d0cSJohn Levon 		estate_set_capped(tmp);
55efe51d0cSJohn Levon 
56c85f09ccSJohn Levon 	if (estate_treat_untagged(s1) && estate_treat_untagged(s2))
57c85f09ccSJohn Levon 		estate_set_treat_untagged(tmp);
58c85f09ccSJohn Levon 
59*6523a3aaSJohn Levon 	if (estate_new(s1) || estate_new(s2))
60*6523a3aaSJohn Levon 		estate_set_new(tmp);
61*6523a3aaSJohn Levon 
621f5207b7SJohn Levon 	return tmp;
631f5207b7SJohn Levon }
641f5207b7SJohn Levon 
get_dinfo(struct smatch_state * state)651f5207b7SJohn Levon struct data_info *get_dinfo(struct smatch_state *state)
661f5207b7SJohn Levon {
671f5207b7SJohn Levon 	if (!state)
681f5207b7SJohn Levon 		return NULL;
691f5207b7SJohn Levon 	return (struct data_info *)state->data;
701f5207b7SJohn Levon }
711f5207b7SJohn Levon 
estate_rl(struct smatch_state * state)721f5207b7SJohn Levon struct range_list *estate_rl(struct smatch_state *state)
731f5207b7SJohn Levon {
741f5207b7SJohn Levon 	if (!state)
751f5207b7SJohn Levon 		return NULL;
761f5207b7SJohn Levon 	return get_dinfo(state)->value_ranges;
771f5207b7SJohn Levon }
781f5207b7SJohn Levon 
estate_related(struct smatch_state * state)791f5207b7SJohn Levon struct related_list *estate_related(struct smatch_state *state)
801f5207b7SJohn Levon {
811f5207b7SJohn Levon 	if (!state)
821f5207b7SJohn Levon 		return NULL;
831f5207b7SJohn Levon 	return get_dinfo(state)->related;
841f5207b7SJohn Levon }
851f5207b7SJohn Levon 
estate_get_fuzzy_max(struct smatch_state * state)861f5207b7SJohn Levon sval_t estate_get_fuzzy_max(struct smatch_state *state)
871f5207b7SJohn Levon {
881f5207b7SJohn Levon 	sval_t empty = {};
891f5207b7SJohn Levon 
901f5207b7SJohn Levon 	if (!state || !get_dinfo(state))
911f5207b7SJohn Levon 		return empty;
921f5207b7SJohn Levon 	return get_dinfo(state)->fuzzy_max;
931f5207b7SJohn Levon }
941f5207b7SJohn Levon 
estate_has_fuzzy_max(struct smatch_state * state)951f5207b7SJohn Levon int estate_has_fuzzy_max(struct smatch_state *state)
961f5207b7SJohn Levon {
971f5207b7SJohn Levon 	if (estate_get_fuzzy_max(state).type)
981f5207b7SJohn Levon 		return 1;
991f5207b7SJohn Levon 	return 0;
1001f5207b7SJohn Levon }
1011f5207b7SJohn Levon 
estate_set_fuzzy_max(struct smatch_state * state,sval_t fuzzy_max)1021f5207b7SJohn Levon void estate_set_fuzzy_max(struct smatch_state *state, sval_t fuzzy_max)
1031f5207b7SJohn Levon {
1041f5207b7SJohn Levon 	if (!rl_has_sval(estate_rl(state), fuzzy_max))
1051f5207b7SJohn Levon 		return;
1061f5207b7SJohn Levon 	get_dinfo(state)->fuzzy_max = fuzzy_max;
1071f5207b7SJohn Levon }
1081f5207b7SJohn Levon 
estate_copy_fuzzy_max(struct smatch_state * new,struct smatch_state * old)1091f5207b7SJohn Levon void estate_copy_fuzzy_max(struct smatch_state *new, struct smatch_state *old)
1101f5207b7SJohn Levon {
1111f5207b7SJohn Levon 	if (!estate_has_fuzzy_max(old))
1121f5207b7SJohn Levon 		return;
1131f5207b7SJohn Levon 	estate_set_fuzzy_max(new, estate_get_fuzzy_max(old));
1141f5207b7SJohn Levon }
1151f5207b7SJohn Levon 
estate_clear_fuzzy_max(struct smatch_state * state)1161f5207b7SJohn Levon void estate_clear_fuzzy_max(struct smatch_state *state)
1171f5207b7SJohn Levon {
1181f5207b7SJohn Levon 	sval_t empty = {};
1191f5207b7SJohn Levon 
1201f5207b7SJohn Levon 	get_dinfo(state)->fuzzy_max = empty;
1211f5207b7SJohn Levon }
1221f5207b7SJohn Levon 
estate_has_hard_max(struct smatch_state * state)1231f5207b7SJohn Levon int estate_has_hard_max(struct smatch_state *state)
1241f5207b7SJohn Levon {
125c85f09ccSJohn Levon 	if (!state || !estate_rl(state))
1261f5207b7SJohn Levon 		return 0;
1271f5207b7SJohn Levon 	return get_dinfo(state)->hard_max;
1281f5207b7SJohn Levon }
1291f5207b7SJohn Levon 
estate_set_hard_max(struct smatch_state * state)1301f5207b7SJohn Levon void estate_set_hard_max(struct smatch_state *state)
1311f5207b7SJohn Levon {
132*6523a3aaSJohn Levon 	/* pointers don't have a hard max */
133*6523a3aaSJohn Levon 	if (is_ptr_type(estate_type(state)))
134*6523a3aaSJohn Levon 		return;
1351f5207b7SJohn Levon 	get_dinfo(state)->hard_max = 1;
1361f5207b7SJohn Levon }
1371f5207b7SJohn Levon 
estate_clear_hard_max(struct smatch_state * state)1381f5207b7SJohn Levon void estate_clear_hard_max(struct smatch_state *state)
1391f5207b7SJohn Levon {
1401f5207b7SJohn Levon 	get_dinfo(state)->hard_max = 0;
1411f5207b7SJohn Levon }
1421f5207b7SJohn Levon 
estate_get_hard_max(struct smatch_state * state,sval_t * sval)1431f5207b7SJohn Levon int estate_get_hard_max(struct smatch_state *state, sval_t *sval)
1441f5207b7SJohn Levon {
1451f5207b7SJohn Levon 	if (!state || !get_dinfo(state)->hard_max || !estate_rl(state))
1461f5207b7SJohn Levon 		return 0;
1471f5207b7SJohn Levon 	*sval = rl_max(estate_rl(state));
1481f5207b7SJohn Levon 	return 1;
1491f5207b7SJohn Levon }
1501f5207b7SJohn Levon 
estate_capped(struct smatch_state * state)151efe51d0cSJohn Levon bool estate_capped(struct smatch_state *state)
152efe51d0cSJohn Levon {
153efe51d0cSJohn Levon 	if (!state)
154efe51d0cSJohn Levon 		return false;
155efe51d0cSJohn Levon 	/* impossible states are capped */
156efe51d0cSJohn Levon 	if (!estate_rl(state))
157efe51d0cSJohn Levon 		return true;
158efe51d0cSJohn Levon 	return get_dinfo(state)->capped;
159efe51d0cSJohn Levon }
160efe51d0cSJohn Levon 
estate_set_capped(struct smatch_state * state)161efe51d0cSJohn Levon void estate_set_capped(struct smatch_state *state)
162efe51d0cSJohn Levon {
163efe51d0cSJohn Levon 	get_dinfo(state)->capped = true;
164efe51d0cSJohn Levon }
165efe51d0cSJohn Levon 
estate_treat_untagged(struct smatch_state * state)166c85f09ccSJohn Levon bool estate_treat_untagged(struct smatch_state *state)
167c85f09ccSJohn Levon {
168c85f09ccSJohn Levon 	if (!state)
169c85f09ccSJohn Levon 		return false;
170c85f09ccSJohn Levon 
171c85f09ccSJohn Levon 	/* impossible states are capped */
172c85f09ccSJohn Levon 	if (!estate_rl(state))
173c85f09ccSJohn Levon 		return true;
174c85f09ccSJohn Levon 
175c85f09ccSJohn Levon 	return get_dinfo(state)->treat_untagged;
176c85f09ccSJohn Levon }
177c85f09ccSJohn Levon 
estate_set_treat_untagged(struct smatch_state * state)178c85f09ccSJohn Levon void estate_set_treat_untagged(struct smatch_state *state)
179c85f09ccSJohn Levon {
180c85f09ccSJohn Levon 	get_dinfo(state)->treat_untagged = true;
181c85f09ccSJohn Levon }
182c85f09ccSJohn Levon 
estate_new(struct smatch_state * state)183*6523a3aaSJohn Levon bool estate_new(struct smatch_state *state)
184*6523a3aaSJohn Levon {
185*6523a3aaSJohn Levon 	if (!estate_rl(state))
186*6523a3aaSJohn Levon 		return false;
187*6523a3aaSJohn Levon 	return get_dinfo(state)->set;
188*6523a3aaSJohn Levon }
189*6523a3aaSJohn Levon 
estate_set_new(struct smatch_state * state)190*6523a3aaSJohn Levon void estate_set_new(struct smatch_state *state)
191*6523a3aaSJohn Levon {
192*6523a3aaSJohn Levon 	get_dinfo(state)->set = true;
193*6523a3aaSJohn Levon }
194*6523a3aaSJohn Levon 
estate_min(struct smatch_state * state)1951f5207b7SJohn Levon sval_t estate_min(struct smatch_state *state)
1961f5207b7SJohn Levon {
1971f5207b7SJohn Levon 	return rl_min(estate_rl(state));
1981f5207b7SJohn Levon }
1991f5207b7SJohn Levon 
estate_max(struct smatch_state * state)2001f5207b7SJohn Levon sval_t estate_max(struct smatch_state *state)
2011f5207b7SJohn Levon {
2021f5207b7SJohn Levon 	return rl_max(estate_rl(state));
2031f5207b7SJohn Levon }
2041f5207b7SJohn Levon 
estate_type(struct smatch_state * state)2051f5207b7SJohn Levon struct symbol *estate_type(struct smatch_state *state)
2061f5207b7SJohn Levon {
2071f5207b7SJohn Levon 	return rl_max(estate_rl(state)).type;
2081f5207b7SJohn Levon }
2091f5207b7SJohn Levon 
rlists_equiv(struct related_list * one,struct related_list * two)2101f5207b7SJohn Levon static int rlists_equiv(struct related_list *one, struct related_list *two)
2111f5207b7SJohn Levon {
2121f5207b7SJohn Levon 	struct relation *one_rel;
2131f5207b7SJohn Levon 	struct relation *two_rel;
2141f5207b7SJohn Levon 
2151f5207b7SJohn Levon 	PREPARE_PTR_LIST(one, one_rel);
2161f5207b7SJohn Levon 	PREPARE_PTR_LIST(two, two_rel);
2171f5207b7SJohn Levon 	for (;;) {
2181f5207b7SJohn Levon 		if (!one_rel && !two_rel)
2191f5207b7SJohn Levon 			return 1;
2201f5207b7SJohn Levon 		if (!one_rel || !two_rel)
2211f5207b7SJohn Levon 			return 0;
2221f5207b7SJohn Levon 		if (one_rel->sym != two_rel->sym)
2231f5207b7SJohn Levon 			return 0;
2241f5207b7SJohn Levon 		if (strcmp(one_rel->name, two_rel->name))
2251f5207b7SJohn Levon 			return 0;
2261f5207b7SJohn Levon 		NEXT_PTR_LIST(one_rel);
2271f5207b7SJohn Levon 		NEXT_PTR_LIST(two_rel);
2281f5207b7SJohn Levon 	}
2291f5207b7SJohn Levon 	FINISH_PTR_LIST(two_rel);
2301f5207b7SJohn Levon 	FINISH_PTR_LIST(one_rel);
2311f5207b7SJohn Levon 
2321f5207b7SJohn Levon 	return 1;
2331f5207b7SJohn Levon }
2341f5207b7SJohn Levon 
estates_equiv(struct smatch_state * one,struct smatch_state * two)2351f5207b7SJohn Levon int estates_equiv(struct smatch_state *one, struct smatch_state *two)
2361f5207b7SJohn Levon {
2371f5207b7SJohn Levon 	if (!one || !two)
2381f5207b7SJohn Levon 		return 0;
2391f5207b7SJohn Levon 	if (one == two)
2401f5207b7SJohn Levon 		return 1;
2411f5207b7SJohn Levon 	if (!rlists_equiv(estate_related(one), estate_related(two)))
2421f5207b7SJohn Levon 		return 0;
243efe51d0cSJohn Levon 	if (estate_capped(one) != estate_capped(two))
244efe51d0cSJohn Levon 		return 0;
245c85f09ccSJohn Levon 	if (estate_treat_untagged(one) != estate_treat_untagged(two))
246c85f09ccSJohn Levon 		return 0;
247*6523a3aaSJohn Levon 	if (estate_has_hard_max(one) != estate_has_hard_max(two))
248*6523a3aaSJohn Levon 		return 0;
249*6523a3aaSJohn Levon 	if (estate_new(one) != estate_new(two))
250*6523a3aaSJohn Levon 		return 0;
2511f5207b7SJohn Levon 	if (strcmp(one->name, two->name) == 0)
2521f5207b7SJohn Levon 		return 1;
2531f5207b7SJohn Levon 	return 0;
2541f5207b7SJohn Levon }
2551f5207b7SJohn Levon 
estate_is_whole(struct smatch_state * state)2561f5207b7SJohn Levon int estate_is_whole(struct smatch_state *state)
2571f5207b7SJohn Levon {
2581f5207b7SJohn Levon 	return is_whole_rl(estate_rl(state));
2591f5207b7SJohn Levon }
2601f5207b7SJohn Levon 
estate_is_empty(struct smatch_state * state)2611f5207b7SJohn Levon int estate_is_empty(struct smatch_state *state)
2621f5207b7SJohn Levon {
2631f5207b7SJohn Levon 	return state && !estate_rl(state);
2641f5207b7SJohn Levon }
2651f5207b7SJohn Levon 
estate_is_unknown(struct smatch_state * state)2661f5207b7SJohn Levon int estate_is_unknown(struct smatch_state *state)
2671f5207b7SJohn Levon {
2681f5207b7SJohn Levon 	if (!estate_is_whole(state))
2691f5207b7SJohn Levon 		return 0;
2701f5207b7SJohn Levon 	if (estate_related(state))
2711f5207b7SJohn Levon 		return 0;
2721f5207b7SJohn Levon 	if (estate_has_fuzzy_max(state))
2731f5207b7SJohn Levon 		return 0;
2741f5207b7SJohn Levon 	return 1;
2751f5207b7SJohn Levon }
2761f5207b7SJohn Levon 
estate_get_single_value(struct smatch_state * state,sval_t * sval)2771f5207b7SJohn Levon int estate_get_single_value(struct smatch_state *state, sval_t *sval)
2781f5207b7SJohn Levon {
2791f5207b7SJohn Levon 	sval_t min, max;
2801f5207b7SJohn Levon 
281c85f09ccSJohn Levon 	if (!estate_rl(state))
282c85f09ccSJohn Levon 		return 0;
2831f5207b7SJohn Levon 	min = rl_min(estate_rl(state));
2841f5207b7SJohn Levon 	max = rl_max(estate_rl(state));
2851f5207b7SJohn Levon 	if (sval_cmp(min, max) != 0)
2861f5207b7SJohn Levon 		return 0;
2871f5207b7SJohn Levon 	*sval = min;
2881f5207b7SJohn Levon 	return 1;
2891f5207b7SJohn Levon }
2901f5207b7SJohn Levon 
alloc_dinfo(void)2911f5207b7SJohn Levon static struct data_info *alloc_dinfo(void)
2921f5207b7SJohn Levon {
2931f5207b7SJohn Levon 	struct data_info *ret;
2941f5207b7SJohn Levon 
2951f5207b7SJohn Levon 	ret = __alloc_data_info(0);
2961f5207b7SJohn Levon 	memset(ret, 0, sizeof(*ret));
2971f5207b7SJohn Levon 	return ret;
2981f5207b7SJohn Levon }
2991f5207b7SJohn Levon 
alloc_dinfo_range(sval_t min,sval_t max)3001f5207b7SJohn Levon static struct data_info *alloc_dinfo_range(sval_t min, sval_t max)
3011f5207b7SJohn Levon {
3021f5207b7SJohn Levon 	struct data_info *ret;
3031f5207b7SJohn Levon 
3041f5207b7SJohn Levon 	ret = alloc_dinfo();
3051f5207b7SJohn Levon 	add_range(&ret->value_ranges, min, max);
3061f5207b7SJohn Levon 	return ret;
3071f5207b7SJohn Levon }
3081f5207b7SJohn Levon 
alloc_dinfo_range_list(struct range_list * rl)3091f5207b7SJohn Levon static struct data_info *alloc_dinfo_range_list(struct range_list *rl)
3101f5207b7SJohn Levon {
3111f5207b7SJohn Levon 	struct data_info *ret;
3121f5207b7SJohn Levon 
3131f5207b7SJohn Levon 	ret = alloc_dinfo();
3141f5207b7SJohn Levon 	ret->value_ranges = rl;
3151f5207b7SJohn Levon 	return ret;
3161f5207b7SJohn Levon }
3171f5207b7SJohn Levon 
clone_dinfo(struct data_info * dinfo)3181f5207b7SJohn Levon static struct data_info *clone_dinfo(struct data_info *dinfo)
3191f5207b7SJohn Levon {
3201f5207b7SJohn Levon 	struct data_info *ret;
3211f5207b7SJohn Levon 
3221f5207b7SJohn Levon 	ret = alloc_dinfo();
3231f5207b7SJohn Levon 	ret->related = clone_related_list(dinfo->related);
3241f5207b7SJohn Levon 	ret->value_ranges = clone_rl(dinfo->value_ranges);
3251f5207b7SJohn Levon 	ret->hard_max = dinfo->hard_max;
3261f5207b7SJohn Levon 	ret->fuzzy_max = dinfo->fuzzy_max;
3271f5207b7SJohn Levon 	return ret;
3281f5207b7SJohn Levon }
3291f5207b7SJohn Levon 
clone_estate(struct smatch_state * state)3301f5207b7SJohn Levon struct smatch_state *clone_estate(struct smatch_state *state)
3311f5207b7SJohn Levon {
3321f5207b7SJohn Levon 	struct smatch_state *ret;
3331f5207b7SJohn Levon 
3341f5207b7SJohn Levon 	if (!state)
3351f5207b7SJohn Levon 		return NULL;
3361f5207b7SJohn Levon 
3371f5207b7SJohn Levon 	ret = __alloc_smatch_state(0);
3381f5207b7SJohn Levon 	ret->name = state->name;
3391f5207b7SJohn Levon 	ret->data = clone_dinfo(get_dinfo(state));
3401f5207b7SJohn Levon 	return ret;
3411f5207b7SJohn Levon }
3421f5207b7SJohn Levon 
clone_partial_estate(struct smatch_state * state,struct range_list * rl)343efe51d0cSJohn Levon struct smatch_state *clone_partial_estate(struct smatch_state *state, struct range_list *rl)
344efe51d0cSJohn Levon {
345efe51d0cSJohn Levon 	struct smatch_state *ret;
346efe51d0cSJohn Levon 
347efe51d0cSJohn Levon 	if (!state)
348efe51d0cSJohn Levon 		return NULL;
349efe51d0cSJohn Levon 
350efe51d0cSJohn Levon 	rl = cast_rl(estate_type(state), rl);
351efe51d0cSJohn Levon 
352efe51d0cSJohn Levon 	ret = alloc_estate_rl(rl);
353efe51d0cSJohn Levon 	set_related(ret, clone_related_list(estate_related(state)));
354efe51d0cSJohn Levon 	if (estate_has_hard_max(state))
355efe51d0cSJohn Levon 		estate_set_hard_max(ret);
356efe51d0cSJohn Levon 	if (estate_has_fuzzy_max(state))
357efe51d0cSJohn Levon 		estate_set_fuzzy_max(ret, estate_get_fuzzy_max(state));
358efe51d0cSJohn Levon 
359efe51d0cSJohn Levon 	return ret;
360efe51d0cSJohn Levon }
361efe51d0cSJohn Levon 
alloc_estate_empty(void)3621f5207b7SJohn Levon struct smatch_state *alloc_estate_empty(void)
3631f5207b7SJohn Levon {
3641f5207b7SJohn Levon 	struct smatch_state *state;
3651f5207b7SJohn Levon 	struct data_info *dinfo;
3661f5207b7SJohn Levon 
3671f5207b7SJohn Levon 	dinfo = alloc_dinfo();
3681f5207b7SJohn Levon 	state = __alloc_smatch_state(0);
3691f5207b7SJohn Levon 	state->data = dinfo;
3701f5207b7SJohn Levon 	state->name = "";
3711f5207b7SJohn Levon 	return state;
3721f5207b7SJohn Levon }
3731f5207b7SJohn Levon 
alloc_estate_whole(struct symbol * type)3741f5207b7SJohn Levon struct smatch_state *alloc_estate_whole(struct symbol *type)
3751f5207b7SJohn Levon {
3761f5207b7SJohn Levon 	return alloc_estate_rl(alloc_whole_rl(type));
3771f5207b7SJohn Levon }
3781f5207b7SJohn Levon 
extra_empty(void)3791f5207b7SJohn Levon struct smatch_state *extra_empty(void)
3801f5207b7SJohn Levon {
3811f5207b7SJohn Levon 	struct smatch_state *ret;
3821f5207b7SJohn Levon 
3831f5207b7SJohn Levon 	ret = __alloc_smatch_state(0);
3841f5207b7SJohn Levon 	ret->name = "empty";
3851f5207b7SJohn Levon 	ret->data = alloc_dinfo();
3861f5207b7SJohn Levon 	return ret;
3871f5207b7SJohn Levon }
3881f5207b7SJohn Levon 
alloc_estate_sval(sval_t sval)3891f5207b7SJohn Levon struct smatch_state *alloc_estate_sval(sval_t sval)
3901f5207b7SJohn Levon {
3911f5207b7SJohn Levon 	struct smatch_state *state;
3921f5207b7SJohn Levon 
3931f5207b7SJohn Levon 	state = __alloc_smatch_state(0);
3941f5207b7SJohn Levon 	state->data = alloc_dinfo_range(sval, sval);
3951f5207b7SJohn Levon 	state->name = show_rl(get_dinfo(state)->value_ranges);
3961f5207b7SJohn Levon 	estate_set_hard_max(state);
3971f5207b7SJohn Levon 	estate_set_fuzzy_max(state, sval);
3981f5207b7SJohn Levon 	return state;
3991f5207b7SJohn Levon }
4001f5207b7SJohn Levon 
alloc_estate_range(sval_t min,sval_t max)4011f5207b7SJohn Levon struct smatch_state *alloc_estate_range(sval_t min, sval_t max)
4021f5207b7SJohn Levon {
4031f5207b7SJohn Levon 	struct smatch_state *state;
4041f5207b7SJohn Levon 
4051f5207b7SJohn Levon 	state = __alloc_smatch_state(0);
4061f5207b7SJohn Levon 	state->data = alloc_dinfo_range(min, max);
4071f5207b7SJohn Levon 	state->name = show_rl(get_dinfo(state)->value_ranges);
4081f5207b7SJohn Levon 	return state;
4091f5207b7SJohn Levon }
4101f5207b7SJohn Levon 
alloc_estate_rl(struct range_list * rl)4111f5207b7SJohn Levon struct smatch_state *alloc_estate_rl(struct range_list *rl)
4121f5207b7SJohn Levon {
4131f5207b7SJohn Levon 	struct smatch_state *state;
4141f5207b7SJohn Levon 
4151f5207b7SJohn Levon 	if (!rl)
4161f5207b7SJohn Levon 		return extra_empty();
4171f5207b7SJohn Levon 
4181f5207b7SJohn Levon 	state = __alloc_smatch_state(0);
4191f5207b7SJohn Levon 	state->data = alloc_dinfo_range_list(rl);
4201f5207b7SJohn Levon 	state->name = show_rl(rl);
4211f5207b7SJohn Levon 	return state;
4221f5207b7SJohn Levon }
4231f5207b7SJohn Levon 
clone_estate_cast(struct symbol * type,struct smatch_state * state)4241f5207b7SJohn Levon struct smatch_state *clone_estate_cast(struct symbol *type, struct smatch_state *state)
4251f5207b7SJohn Levon {
4261f5207b7SJohn Levon 	struct smatch_state *ret;
4271f5207b7SJohn Levon 	struct data_info *dinfo;
4281f5207b7SJohn Levon 
4291f5207b7SJohn Levon 	if (!state)
4301f5207b7SJohn Levon 		return NULL;
4311f5207b7SJohn Levon 
4321f5207b7SJohn Levon 	dinfo = alloc_dinfo();
4331f5207b7SJohn Levon 	dinfo->value_ranges = clone_rl(cast_rl(type, estate_rl(state)));
4341f5207b7SJohn Levon 
4351f5207b7SJohn Levon 	ret = __alloc_smatch_state(0);
4361f5207b7SJohn Levon 	ret->name = show_rl(dinfo->value_ranges);
4371f5207b7SJohn Levon 	ret->data = dinfo;
4381f5207b7SJohn Levon 
4391f5207b7SJohn Levon 	return ret;
4401f5207b7SJohn Levon }
4411f5207b7SJohn Levon 
get_implied_estate(struct expression * expr)4421f5207b7SJohn Levon struct smatch_state *get_implied_estate(struct expression *expr)
4431f5207b7SJohn Levon {
4441f5207b7SJohn Levon 	struct smatch_state *state;
4451f5207b7SJohn Levon 	struct range_list *rl;
4461f5207b7SJohn Levon 
4471f5207b7SJohn Levon 	state = get_state_expr(SMATCH_EXTRA, expr);
4481f5207b7SJohn Levon 	if (state)
4491f5207b7SJohn Levon 		return state;
4501f5207b7SJohn Levon 	if (!get_implied_rl(expr, &rl))
4511f5207b7SJohn Levon 		rl = alloc_whole_rl(get_type(expr));
4521f5207b7SJohn Levon 	return alloc_estate_rl(rl);
4531f5207b7SJohn Levon }
4541f5207b7SJohn Levon 
4551f5207b7SJohn Levon /*
4561f5207b7SJohn Levon  * One of the complications is that smatch tries to free a bunch of data at the
4571f5207b7SJohn Levon  * end of every function.
4581f5207b7SJohn Levon  */
clone_dinfo_perm(struct data_info * dinfo)4591f5207b7SJohn Levon struct data_info *clone_dinfo_perm(struct data_info *dinfo)
4601f5207b7SJohn Levon {
4611f5207b7SJohn Levon 	struct data_info *ret;
4621f5207b7SJohn Levon 
4631f5207b7SJohn Levon 	ret = malloc(sizeof(*ret));
4641f5207b7SJohn Levon 	memset(ret, 0, sizeof(*ret));
4651f5207b7SJohn Levon 	ret->related = NULL;
4661f5207b7SJohn Levon 	ret->value_ranges = clone_rl_permanent(dinfo->value_ranges);
4671f5207b7SJohn Levon 	ret->hard_max = 0;
4681f5207b7SJohn Levon 	ret->fuzzy_max = dinfo->fuzzy_max;
4691f5207b7SJohn Levon 	return ret;
4701f5207b7SJohn Levon }
4711f5207b7SJohn Levon 
clone_estate_perm(struct smatch_state * state)4721f5207b7SJohn Levon struct smatch_state *clone_estate_perm(struct smatch_state *state)
4731f5207b7SJohn Levon {
4741f5207b7SJohn Levon 	struct smatch_state *ret;
4751f5207b7SJohn Levon 
4761f5207b7SJohn Levon 	ret = malloc(sizeof(*ret));
4771f5207b7SJohn Levon 	ret->name = alloc_string(state->name);
4781f5207b7SJohn Levon 	ret->data = clone_dinfo_perm(get_dinfo(state));
4791f5207b7SJohn Levon 	return ret;
4801f5207b7SJohn Levon }
4811f5207b7SJohn Levon 
4821f5207b7SJohn Levon 
483