]> andersk Git - splint.git/blob - src/mtContextNode.c
noexpand always false.
[splint.git] / src / mtContextNode.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 ** 
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** General Public License for more details.
15 ** 
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
19 **
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24 /*
25 ** mtContextNode.c
26 */
27
28 # include "splintMacros.nf"
29 # include "basic.h"
30
31 static bool mtContextNode_matchesType (mtContextNode, ctype) /*@*/ ;
32
33 static /*@observer@*/ cstring mtContextKind_unparse (mtContextKind ck)
34 {
35   switch (ck)
36     {
37     case MTC_ANY: return cstring_makeLiteralTemp ("any");
38     case MTC_PARAM: return cstring_makeLiteralTemp ("parameter"); 
39     case MTC_RESULT: return cstring_makeLiteralTemp ("result"); 
40     case MTC_REFERENCE: return cstring_makeLiteralTemp ("reference");
41     case MTC_CLAUSE: return cstring_makeLiteralTemp ("clause");
42     case MTC_LITERAL: return cstring_makeLiteralTemp ("literal");
43     case MTC_NULL: return cstring_makeLiteralTemp ("null");
44     }
45
46   BADBRANCHRET (cstring_undefined);
47 }
48  
49 static mtContextNode mtContextNode_create (mtContextKind context, ctype ct) 
50 {
51   mtContextNode res = (mtContextNode) dmalloc (sizeof (*res));
52   res->context = context;
53   res->type = ct;
54   DPRINTF (("Create: %s", mtContextNode_unparse (res)));
55   return res;
56 }
57
58 extern mtContextNode mtContextNode_createAny ()
59 {
60   return mtContextNode_create (MTC_ANY, ctype_unknown);
61 }
62
63 extern mtContextNode mtContextNode_createParameter (ctype ct) 
64 {
65   return mtContextNode_create (MTC_PARAM, ct);
66 }
67
68 extern mtContextNode mtContextNode_createResult (ctype ct) 
69 {
70   return mtContextNode_create (MTC_RESULT, ct);
71 }
72
73 extern mtContextNode mtContextNode_createReference (ctype ct) 
74 {
75   return mtContextNode_create (MTC_REFERENCE, ct);
76 }
77
78 extern mtContextNode mtContextNode_createClause (ctype ct) 
79 {
80   return mtContextNode_create (MTC_CLAUSE, ct);
81 }
82
83 extern mtContextNode mtContextNode_createLiteral (ctype ct) 
84 {
85   return mtContextNode_create (MTC_LITERAL, ct);
86 }
87
88 extern mtContextNode mtContextNode_createNull (ctype ct) 
89 {
90   return mtContextNode_create (MTC_NULL, ct);
91 }
92
93 extern void mtContextNode_free (/*@only@*/ mtContextNode node) 
94 {
95   sfree (node);
96 }
97
98 bool mtContextNode_matchesEntry (mtContextNode context, uentry ue)
99 {
100   ctype ct;
101
102   llassert (mtContextNode_isDefined (context));
103
104   DPRINTF (("Matches context: %s / %s",
105             mtContextNode_unparse (context), uentry_unparse (ue)));
106
107   switch (context->context)
108     {
109     case MTC_ANY: break; /* everything matches */
110     case MTC_RESULT:
111       if (!uentry_isFunction (ue))
112         {
113           return FALSE;
114         }
115       break;
116     case MTC_PARAM: 
117       if (!uentry_isAnyParam (ue))
118         {
119           DPRINTF (("not param: %s", uentry_unparseFull (ue)));
120           return FALSE;
121         }
122       break;
123     case MTC_LITERAL:
124     case MTC_NULL:
125       return FALSE;
126     case MTC_REFERENCE:
127       break;
128     case MTC_CLAUSE:
129       BADBRANCH;
130     }
131
132   if (uentry_isFunction (ue))
133     {
134       ct = ctype_getReturnType (uentry_getType (ue));
135     }
136   else
137     {
138       ct = uentry_getType (ue);
139     }
140
141   return mtContextNode_matchesType (context, ct);
142 }
143
144 bool mtContextNode_matchesRef (mtContextNode context, sRef sr)
145 {
146   ctype ct;
147
148   llassert (mtContextNode_isDefined (context));
149
150   DPRINTF (("Matches context: %s / %s",
151             mtContextNode_unparse (context), sRef_unparse (sr)));
152
153   switch (context->context)
154     {
155     case MTC_ANY: break; /* everything matches */
156     case MTC_RESULT:
157       DPRINTF (("Result? %s / %s",
158                 sRef_unparseFull (sr),
159                 bool_unparse (sRef_isResult (sr))));
160       return sRef_isResult (sr);
161     case MTC_PARAM: 
162       if (!sRef_isParam (sr))
163         {
164           return FALSE;
165         }
166       break;
167     case MTC_LITERAL:
168       DPRINTF (("Literal: %s", sRef_unparse (sr)));
169       if (!sRef_isConst (sr))
170         {
171           return FALSE;
172         }
173       break;
174     case MTC_NULL:
175     case MTC_REFERENCE:
176       break;
177     case MTC_CLAUSE:
178       BADBRANCH;
179     }
180
181   ct = sRef_getType (sr);
182   return mtContextNode_matchesType (context, ct);
183 }
184
185 bool mtContextNode_matchesRefStrict (mtContextNode context, sRef s)
186 {
187   if (mtContextNode_isDefined (context)
188       && mtContextNode_matchesRef (context, s))
189     {
190       if (ctype_isKnown (context->type) 
191           && (ctype_isUnknown (sRef_getType (s))
192               || ctype_isVoidPointer (sRef_getType (s))))
193         {
194           return FALSE;
195         }
196       else
197         {
198           return TRUE;
199         }
200     }
201   
202   return FALSE;
203 }
204
205 bool mtContextNode_matchesType (mtContextNode context, ctype ct)
206 {
207   DPRINTF (("Context type..."));
208   llassert (mtContextNode_isDefined (context));
209   
210   if (!ctype_match (context->type, ct))
211     {
212       DPRINTF (("Type mismatch: %s / %s",
213                 ctype_unparse (context->type),
214                 ctype_unparse (ct)));
215       return FALSE;
216     }
217   else
218     {
219       /* evans 2001-08-21 - don't match if only one type is unknown */
220       if (ctype_isUnknown (ct) && !ctype_isUnknown (context->type))
221         {
222           return FALSE;
223         }
224
225       DPRINTF (("Type okay: %s / %s",
226                 ctype_unparse (context->type),
227                 ctype_unparse (ct)));
228     }
229   
230   return TRUE;
231 }
232
233 cstring mtContextNode_unparse (mtContextNode node)
234 {
235   llassert (mtContextNode_isDefined (node));
236
237   if (ctype_isKnown (node->type))
238     {
239       return message ("%s %s", mtContextKind_unparse (node->context),
240                       ctype_unparse (node->type));
241     }
242   else
243     {
244       return message ("%s", mtContextKind_unparse (node->context));
245     }
246 }
247
248 bool mtContextNode_isClause (mtContextNode n)
249 {
250   llassert (mtContextNode_isDefined (n));
251   return (n->context == MTC_CLAUSE);
252 }
253
254 bool mtContextNode_isParameter (mtContextNode n)
255 {
256   llassert (mtContextNode_isDefined (n));
257   return (n->context == MTC_PARAM);
258 }
259
260 bool mtContextNode_isReference (mtContextNode n)
261 {
262   llassert (mtContextNode_isDefined (n));
263   return (n->context == MTC_REFERENCE);
264 }
265
266 bool mtContextNode_isResult (mtContextNode n)
267 {
268   llassert (mtContextNode_isDefined (n));
269   return (n->context == MTC_RESULT);
270 }
271
272 bool mtContextNode_isLiteral (mtContextNode n)
273 {
274   llassert (mtContextNode_isDefined (n));
275   return (n->context == MTC_LITERAL);
276 }
277
278 bool mtContextNode_isNull (mtContextNode n)
279 {
280   llassert (mtContextNode_isDefined (n));
281   return (n->context == MTC_NULL);
282 }
283
284 void mtContextNode_showRefError (mtContextNode context, sRef sr)
285 {
286   ctype ct;
287
288   llassert (mtContextNode_isDefined (context));
289   llassert (!mtContextNode_matchesRef (context, sr));
290
291   DPRINTF (("Matches context: %s / %s",
292             mtContextNode_unparse (context), sRef_unparse (sr)));
293
294   switch (context->context)
295     {
296     case MTC_ANY: break; /* everything matches */
297     case MTC_RESULT:
298       if (!sRef_isResult (sr))
299         {
300           llgenindentmsgnoloc 
301             (message ("Context is result, doesn't match %q", sRef_unparse (sr)));
302           return;
303         }
304       break;
305     case MTC_PARAM: 
306       if (!sRef_isResult (sr))
307         {
308           llgenindentmsgnoloc 
309             (message ("Context is parameter, doesn't match %q", sRef_unparse (sr)));
310           return;
311         }
312       break;
313     case MTC_LITERAL:
314       DPRINTF (("Literal: %s", sRef_unparse (sr)));
315       if (!sRef_isConst (sr))
316         {
317           llgenindentmsgnoloc
318             (message ("Context is literal, doesn't match %q", sRef_unparse (sr)));
319           return;
320         }
321       break;
322     case MTC_NULL:
323     case MTC_REFERENCE:
324       break;
325     case MTC_CLAUSE:
326       BADBRANCH;
327     }
328
329   ct = sRef_getType (sr);
330   
331   if (!mtContextNode_matchesType (context, ct))
332     {
333       llgenindentmsgnoloc
334         (message ("Context type is %s, doesn't match type %s", 
335                   ctype_unparse (context->type),
336                   ctype_unparse (ct)));
337     }
338   else
339     {
340       BADBRANCH;
341     }
342 }
343
344
345
This page took 0.625258 seconds and 5 git commands to generate.