db: don't turn RaiseError on
[smatch.git] / smatch_scripts / db / fill_db_return_implies.pl
blob27b13152cf3afcbab43719e747f95bfdece0f10f
1 #!/usr/bin/perl
3 use strict;
4 use DBI;
5 use bignum;
7 my $warns = shift;
9 if (!defined($warns)) {
10 print "usage: $0 <warns.txt>\n";
11 exit(1);
14 my $db = DBI->connect("dbi:SQLite:smatch_db.sqlite", "", "", {AutoCommit => 0});
15 $db->do("PRAGMA synchronous = OFF");
16 $db->do("PRAGMA cache_size = 800000");
17 $db->do("PRAGMA journal_mode = OFF");
19 $db->do("delete from return_implies");
21 my $type = 7; # RANGE_CAP
23 sub get_error_num($)
25 my $str = shift;
27 $str =~ s/min/-4095/;
28 if ($str =~ /^\((.*)\)/) {
29 $str = $1;
31 return $str;
34 sub get_num($)
36 my $str = shift;
38 if ($str =~ /^\((.*)\)/) {
39 $str = $1;
41 return $str;
44 sub show_num($)
46 my $str = shift;
48 if ($str =~ /^-/) {
49 $str = "($str)";
51 return $str;
54 sub show_range($$)
56 my $min = shift;
57 my $max = shift;
59 if ($min =~ /^$max$/) {
60 return "$min";
62 return "$min-$max";
65 sub get_error_returns($)
67 my $total_ranges = shift;
68 my @error_ranges;
69 my $ret;
71 foreach my $range (split(",", $total_ranges)) {
72 my ($range_1, $range_2);
73 my ($min, $max);
75 if ($range =~ /(.*[^(])-(.*)/) {
76 $range_1 = $1;
77 $range_2 = $2;
78 } else {
79 $range_1 = $range;
80 $range_2 = $range;
83 $min = get_error_num($range_1);
84 $max = get_error_num($range_2);
86 if ($max + 0 < 0) {
87 push @error_ranges, $range;
88 } elsif ($min + 0 < 0) {
89 push @error_ranges, show_num($min) . "-(-1)";
93 foreach my $range (@error_ranges) {
94 if ($ret) {
95 $ret = $ret . ",";
97 $ret = $ret . $range;
99 return $ret;
102 sub get_success_returns($)
104 my $total_ranges = shift;
105 my @success_ranges;
106 my $ret;
108 foreach my $range (split(",", $total_ranges)) {
109 my ($range_1, $range_2);
110 my ($min, $max);
112 if ($range =~ /(.*[^(])-(.*)/) {
113 $range_1 = $1;
114 $range_2 = $2;
115 } else {
116 $range_1 = $range;
117 $range_2 = $range;
120 $min = get_error_num($range_1);
121 $max = get_error_num($range_2);
123 if ($min + 0 >= 0) {
124 push @success_ranges, $range;
125 } elsif ($max + 0 >= 0 || $max =~ /max/) {
126 push @success_ranges, show_range(0, $range_2);
130 foreach my $range (@success_ranges) {
131 if ($ret) {
132 $ret = $ret . ",";
134 $ret = $ret . $range;
136 return $ret;
139 sub invert_range($)
141 my $orig = shift;
142 my $old_max;
143 my $ret;
145 foreach my $range (split(",", $orig)) {
146 my ($range_1, $range_2);
147 my ($min, $max);
149 if ($range =~ /(.*[^(])-(.*)/) {
150 $range_1 = $1;
151 $range_2 = $2;
152 } else {
153 $range_1 = $range;
154 $range_2 = $range;
157 $min = get_num($range_1);
158 $min = show_num($min - 1);
160 $max = get_num($range_2);
161 $max = show_num($max + 1);
163 if (!defined($old_max)) {
164 if (!($range_1 =~ /min/)) {
165 $ret = "min-" . $min;
167 } else {
168 if ($ret) {
169 $ret = $ret . ",";
172 $ret = $ret . show_range($old_max, $min);
174 $old_max = $max;
177 if (!($orig =~ /max$/)) {
178 if ($ret) {
179 $ret = $ret . ",";
181 $ret = $ret . "$old_max-max";
184 return $ret;
187 my $old_func = "";
188 my $total_returns = "";
190 open(FILE, "<$warns");
191 while (<FILE>) {
192 # test.c:26 func() info: function_return_values '(-20),(-12),0' global
193 if (/.*?:\d+ (\w+)\(\) info: function_return_values '(.*?)'/) {
194 $old_func = $1;
195 $total_returns = $2;
198 # test.c:14 func() info: param 0 range 'min-(-1),12-max' implies error return static
199 if (/(.*?):\d+ (\w+)\(\) info: param (\d+) range '(.*?)' implies error return (global|static)/) {
200 my $file = $1;
201 my $func = $2;
202 my $param = $3;
203 my $bad_range = $4;
205 my $static = 0;
206 if ($5 =~ /static/) {
207 $static = 1;
210 my $error_returns;
211 my $success_returns;
212 my $good_range = invert_range($bad_range);
214 if (!($func =~ /^$old_func$/)) {
215 next;
218 $error_returns = get_error_returns($total_returns);
219 $success_returns = get_success_returns($total_returns);
221 $db->do("insert into return_implies values ('$file', '$func', $static, $type, '$success_returns', $param, '', '$good_range')");
222 $db->do("insert into return_implies values ('$file', '$func', $static, $type, '$error_returns', $param, '', 'min-max')");
225 close(FILE);
228 open(FILE, "<$warns");
229 while (<FILE>) {
230 # crypto/cbc.c:54 is_power_of_2() info: bool_return_implication "1" 0 "min-(-1),1-max static"
231 if (/(.*?):\d+ (\w+)\(\) info: bool_return_implication "(.*?)" (\d+) "(.*?)" (global|static)/) {
232 my $file = $1;
233 my $func = $2;
234 my $return_range = $3;
235 my $param = $4;
236 my $implied_range = $5;
237 my $static = 0;
238 if ($6 =~ /static/) {
239 $static = 1;
242 $db->do("insert into return_implies values ('$file', '$func', $static, $type, '$return_range', $param, '', '$implied_range')");
245 close(FILE);
248 $db->commit();
249 $db->disconnect();