estates: reuse same estate for extra_undefined()
[smatch.git] / smatch_estate.c
blob7e157520f6d4740487656fdb1ed406cf8010d0ec
1 /*
2 * smatch/smatch_dinfo.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * smatch_dinfo.c has helper functions for handling data_info structs
15 #include <stdlib.h>
16 #ifndef __USE_ISOC99
17 #define __USE_ISOC99
18 #endif
19 #include <limits.h>
20 #include "parse.h"
21 #include "smatch.h"
22 #include "smatch_slist.h"
23 #include "smatch_extra.h"
25 struct smatch_state estate_undefined = {
26 .name = "unknown"
29 struct data_info *get_dinfo(struct smatch_state *state)
31 if (!state)
32 return NULL;
33 return (struct data_info *)state->data;
37 struct range_list *estate_ranges(struct smatch_state *state)
39 if (!state)
40 return NULL;
41 return get_dinfo(state)->value_ranges;
44 struct related_list *estate_related(struct smatch_state *state)
46 if (!state)
47 return NULL;
48 return get_dinfo(state)->related;
51 long long estate_min(struct smatch_state *state)
53 return rl_min(estate_ranges(state));
56 long long estate_max(struct smatch_state *state)
58 return rl_max(estate_ranges(state));
61 static struct data_info *alloc_dinfo(void)
63 struct data_info *ret;
65 ret = __alloc_data_info(0);
66 ret->related = NULL;
67 ret->type = DATA_RANGE;
68 ret->value_ranges = NULL;
69 return ret;
72 static struct data_info *alloc_dinfo_range(long long min, long long max)
74 struct data_info *ret;
76 ret = alloc_dinfo();
77 add_range(&ret->value_ranges, min, max);
78 return ret;
81 static struct data_info *alloc_dinfo_range_list(struct range_list *rl)
83 struct data_info *ret;
85 ret = alloc_dinfo();
86 ret->value_ranges = rl;
87 return ret;
90 static struct data_info *clone_dinfo(struct data_info *dinfo)
92 struct data_info *ret;
94 ret = alloc_dinfo();
95 ret->related = clone_related_list(dinfo->related);
96 ret->value_ranges = clone_range_list(dinfo->value_ranges);
97 return ret;
100 struct smatch_state *clone_estate(struct smatch_state *state)
102 struct smatch_state *ret;
104 ret = __alloc_smatch_state(0);
105 ret->name = state->name;
106 ret->data = clone_dinfo(get_dinfo(state));
107 return ret;
110 struct smatch_state *alloc_estate_empty(void)
112 struct smatch_state *state;
113 struct data_info *dinfo;
115 dinfo = alloc_dinfo();
116 state = __alloc_smatch_state(0);
117 state->data = dinfo;
118 state->name = "";
119 return state;
122 static struct smatch_state *alloc_estate_no_name(int val)
124 struct smatch_state *state;
126 state = __alloc_smatch_state(0);
127 state->data = (void *)alloc_dinfo_range(val, val);
128 return state;
131 /* We do this because ->value_ranges is a list */
132 struct smatch_state *extra_undefined(void)
134 return &estate_undefined;
137 struct smatch_state *extra_empty(void)
139 struct smatch_state *ret;
141 ret = __alloc_smatch_state(0);
142 ret->name = "empty";
143 ret->data = alloc_dinfo();
144 return ret;
147 struct smatch_state *alloc_estate(long long val)
149 struct smatch_state *state;
151 state = alloc_estate_no_name(val);
152 state->name = show_ranges(get_dinfo(state)->value_ranges);
153 return state;
156 struct smatch_state *alloc_estate_range(long long min, long long max)
158 struct smatch_state *state;
160 if (min == whole_range.min && max == whole_range.max)
161 return extra_undefined();
162 state = __alloc_smatch_state(0);
163 state->data = (void *)alloc_dinfo_range(min, max);
164 state->name = show_ranges(get_dinfo(state)->value_ranges);
165 return state;
168 struct smatch_state *alloc_estate_range_list(struct range_list *rl)
170 struct smatch_state *state;
172 if (!rl)
173 return extra_empty();
175 if (is_whole_range_rl(rl))
176 return extra_undefined();
178 state = __alloc_smatch_state(0);
179 state->data = (void *)alloc_dinfo_range_list(rl);
180 state->name = show_ranges(get_dinfo(state)->value_ranges);
181 return state;
184 void alloc_estate_undefined(void)
186 static struct data_info dinfo = {
187 .type = DATA_RANGE
190 dinfo.value_ranges = clone_permanent(whole_range_list());
191 estate_undefined.data = &dinfo;