Bug Summary

File:soltools/cpp/_eval.c
Location:line 423, column 9
Description:Assigned value is garbage or undefined

Annotated Source Code

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include "cpp.h"
21
22#define NSTAK32 32
23#define SGN0 0
24#define UNS1 1
25#define UND2 2
26
27#define UNSMARK0x1000 0x1000
28
29struct value
30{
31 long val;
32 int type;
33};
34
35/* conversion types */
36#define RELAT1 1
37#define ARITH2 2
38#define LOGIC3 3
39#define SPCL4 4
40#define SHIFT5 5
41#define UNARY6 6
42
43/* operator priority, arity, and conversion type, indexed by tokentype */
44struct pri
45{
46 char pri;
47 char arity;
48 char ctype;
49} priority[] =
50
51{
52 {
53 0, 0, 0
54 }, /* END */
55 {
56 0, 0, 0
57 }, /* UNCLASS */
58 {
59 0, 0, 0
60 }, /* NAME */
61 {
62 0, 0, 0
63 }, /* NUMBER */
64 {
65 0, 0, 0
66 }, /* STRING */
67 {
68 0, 0, 0
69 }, /* CCON */
70 {
71 0, 0, 0
72 }, /* NL */
73 {
74 0, 0, 0
75 }, /* WS */
76 {
77 0, 0, 0
78 }, /* DSHARP */
79 {
80 11, 2, RELAT1
81 }, /* EQ */
82 {
83 11, 2, RELAT1
84 }, /* NEQ */
85 {
86 12, 2, RELAT1
87 }, /* LEQ */
88 {
89 12, 2, RELAT1
90 }, /* GEQ */
91 {
92 13, 2, SHIFT5
93 }, /* LSH */
94 {
95 13, 2, SHIFT5
96 }, /* RSH */
97 {
98 7, 2, LOGIC3
99 }, /* LAND */
100 {
101 6, 2, LOGIC3
102 }, /* LOR */
103 {
104 0, 0, 0
105 }, /* PPLUS */
106 {
107 0, 0, 0
108 }, /* MMINUS */
109 {
110 0, 0, 0
111 }, /* ARROW */
112 {
113 0, 0, 0
114 }, /* SBRA */
115 {
116 0, 0, 0
117 }, /* SKET */
118 {
119 3, 0, 0
120 }, /* LP */
121 {
122 3, 0, 0
123 }, /* RP */
124 {
125 0, 0, 0
126 }, /* DOT */
127 {
128 10, 2, ARITH2
129 }, /* AND */
130 {
131 15, 2, ARITH2
132 }, /* STAR */
133 {
134 14, 2, ARITH2
135 }, /* PLUS */
136 {
137 14, 2, ARITH2
138 }, /* MINUS */
139 {
140 16, 1, UNARY6
141 }, /* TILDE */
142 {
143 16, 1, UNARY6
144 }, /* NOT */
145 {
146 15, 2, ARITH2
147 }, /* SLASH */
148 {
149 15, 2, ARITH2
150 }, /* PCT */
151 {
152 12, 2, RELAT1
153 }, /* LT */
154 {
155 12, 2, RELAT1
156 }, /* GT */
157 {
158 9, 2, ARITH2
159 }, /* CIRC */
160 {
161 8, 2, ARITH2
162 }, /* OR */
163 {
164 5, 2, SPCL4
165 }, /* QUEST */
166 {
167 5, 2, SPCL4
168 }, /* COLON */
169 {
170 0, 0, 0
171 }, /* ASGN */
172 {
173 4, 2, 0
174 }, /* COMMA */
175 {
176 0, 0, 0
177 }, /* SHARP */
178 {
179 0, 0, 0
180 }, /* SEMIC */
181 {
182 0, 0, 0
183 }, /* CBRA */
184 {
185 0, 0, 0
186 }, /* CKET */
187 {
188 0, 0, 0
189 }, /* ASPLUS */
190 {
191 0, 0, 0
192 }, /* ASMINUS */
193 {
194 0, 0, 0
195 }, /* ASSTAR */
196 {
197 0, 0, 0
198 }, /* ASSLASH */
199 {
200 0, 0, 0
201 }, /* ASPCT */
202 {
203 0, 0, 0
204 }, /* ASCIRC */
205 {
206 0, 0, 0
207 }, /* ASLSH */
208 {
209 0, 0, 0
210 }, /* ASRSH */
211 {
212 0, 0, 0
213 }, /* ASOR */
214 {
215 0, 0, 0
216 }, /* ASAND */
217 {
218 0, 0, 0
219 }, /* ELLIPS */
220 {
221 0, 0, 0
222 }, /* DSHARP1 */
223 {
224 0, 0, 0
225 }, /* NAME1 */
226 {
227 0, 0, 0
228 }, /* NAME2 */
229 {
230 16, 1, UNARY6
231 }, /* DEFINED */
232 {
233 16, 0, UNARY6
234 }, /* UMINUS */
235 {
236 16, 1, UNARY6
237 }, /* ARCHITECTURE */
238};
239
240int evalop(struct pri);
241struct value tokval(Token *);
242struct value vals[NSTAK32], *vp;
243enum toktype ops[NSTAK32], *op;
244
245/*
246 * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword.
247 */
248long
249 eval(Tokenrow * trp, int kw)
250{
251 Token *tp;
252 Nlist *np;
253 size_t ntok;
254 int rnd;
255
256 trp->tp++;
257 if (kw == KIFDEF || kw == KIFNDEF)
258 {
259 if (trp->lp - trp->bp != 4 || trp->tp->type != NAME)
260 {
261 error(ERROR, "Syntax error in #ifdef/#ifndef");
262 return 0;
263 }
264 np = lookup(trp->tp, 0);
265 return (kw == KIFDEF) == (np && np->flag & (ISDEFINED0x01 | ISMAC0x08));
266 }
267 ntok = trp->tp - trp->bp;
268 kwdefined->val = KDEFINED; /* activate special meaning of
269 * defined */
270 expandrow(trp, "<if>");
271 kwdefined->val = NAME;
272 vp = vals;
273 op = ops;
274 *op++ = END;
275 for (rnd = 0, tp = trp->bp + ntok; tp < trp->lp; tp++)
276 {
277 switch (tp->type)
278 {
279 case WS:
280 case NL:
281 continue;
282
283 /* nilary */
284 case NAME:
285 case NAME1:
286 case NAME2:
287 case NUMBER:
288 case CCON:
289 case STRING:
290 if (rnd)
291 goto syntax;
292 *vp++ = tokval(tp);
293 rnd = 1;
294 continue;
295
296 /* unary */
297 case DEFINED:
298 case TILDE:
299 case NOT:
300 if (rnd)
301 goto syntax;
302 *op++ = tp->type;
303 continue;
304
305 /* unary-binary */
306 case PLUS:
307 case MINUS:
308 case STAR:
309 case AND:
310 if (rnd == 0)
311 {
312 if (tp->type == MINUS)
313 *op++ = UMINUS;
314 if (tp->type == STAR || tp->type == AND)
315 {
316 error(ERROR, "Illegal operator * or & in #if/#elsif");
317 return 0;
318 }
319 continue;
320 }
321 /* flow through */
322
323 /* plain binary */
324 case EQ:
325 case NEQ:
326 case LEQ:
327 case GEQ:
328 case LSH:
329 case RSH:
330 case LAND:
331 case LOR:
332 case SLASH:
333 case PCT:
334 case LT:
335 case GT:
336 case CIRC:
337 case OR:
338 case QUEST:
339 case COLON:
340 case COMMA:
341 if (rnd == 0)
342 goto syntax;
343 if (evalop(priority[tp->type]) != 0)
344 return 0;
345 *op++ = tp->type;
346 rnd = 0;
347 continue;
348
349 case LP:
350 if (rnd)
351 goto syntax;
352 *op++ = LP;
353 continue;
354
355 case RP:
356 if (!rnd)
357 goto syntax;
358 if (evalop(priority[RP]) != 0)
359 return 0;
360 if (op <= ops || op[-1] != LP)
361 {
362 goto syntax;
363 }
364 op--;
365 continue;
366
367 case SHARP:
368 if ((tp + 1) < trp->lp)
369 {
370 np = lookup(tp + 1, 0);
371 if (np && (np->val == KMACHINE))
372 {
373 tp++;
374 if (rnd)
375 goto syntax;
376 *op++ = ARCHITECTURE;
377 continue;
378 }
379 }
380 /* fall through */
381
382 default:
383 error(ERROR, "Bad operator (%t) in #if/#elsif", tp);
384 return 0;
385 }
386 }
387 if (rnd == 0)
388 goto syntax;
389 if (evalop(priority[END]) != 0)
390 return 0;
391 if (op != &ops[1] || vp != &vals[1])
392 {
393 error(ERROR, "Botch in #if/#elsif");
394 return 0;
395 }
396 if (vals[0].type == UND2)
397 error(ERROR, "Undefined expression value");
398 return vals[0].val;
399syntax:
400 error(ERROR, "Syntax error in #if/#elsif");
401 return 0;
402}
403
404int
405 evalop(struct pri pri)
406{
407 struct value v1;
408 struct value v2 = { 0, UND2 };
409 long rv1, rv2;
410 int rtype, oper;
411
412 rv2 = 0;
413 rtype = 0;
414 while (pri.pri < priority[op[-1]].pri)
1
Loop condition is true. Entering loop body
7
Loop condition is true. Entering loop body
13
Loop condition is true. Entering loop body
21
Loop condition is true. Entering loop body
415 {
416 oper = *--op;
417 if (priority[oper].arity == 2)
2
Taking false branch
8
Taking false branch
14
Taking false branch
22
Taking true branch
418 {
419 v2 = *--vp;
420 rv2 = v2.val;
421 }
422 v1 = *--vp;
423 rv1 = v1.val;
23
Assigned value is garbage or undefined
424/*lint -e574 -e644 */
425 switch (priority[oper].ctype)
3
Control jumps to 'case 3:' at line 456
9
Control jumps to 'case 3:' at line 456
15
Control jumps to 'case 3:' at line 456
426 {
427 case 0:
428 default:
429 error(WARNING, "Syntax error in #if/#endif");
430 return 1;
431 case ARITH2:
432 case RELAT1:
433 if (v1.type == UNS1 || v2.type == UNS1)
434 rtype = UNS1;
435 else
436 rtype = SGN0;
437 if (v1.type == UND2 || v2.type == UND2)
438 rtype = UND2;
439 if (priority[oper].ctype == RELAT1 && rtype == UNS1)
440 {
441 oper |= UNSMARK0x1000;
442 rtype = SGN0;
443 }
444 break;
445 case SHIFT5:
446 if (v1.type == UND2 || v2.type == UND2)
447 rtype = UND2;
448 else
449 rtype = v1.type;
450 if (rtype == UNS1)
451 oper |= UNSMARK0x1000;
452 break;
453 case UNARY6:
454 rtype = v1.type;
455 break;
456 case LOGIC3:
457 case SPCL4:
458 break;
4
Execution continues on line 460
10
Execution continues on line 460
16
Execution continues on line 460
459 }
460 switch (oper)
5
Control jumps to 'case DEFINED:' at line 600
11
Control jumps to 'case DEFINED:' at line 600
17
Control jumps to 'case COLON:' at line 587
461 {
462 case EQ:
463 case EQ | UNSMARK0x1000:
464 rv1 = rv1 == rv2;
465 break;
466 case NEQ:
467 case NEQ | UNSMARK0x1000:
468 rv1 = rv1 != rv2;
469 break;
470 case LEQ:
471 rv1 = rv1 <= rv2;
472 break;
473 case GEQ:
474 rv1 = rv1 >= rv2;
475 break;
476 case LT:
477 rv1 = rv1 < rv2;
478 break;
479 case GT:
480 rv1 = rv1 > rv2;
481 break;
482 case LEQ | UNSMARK0x1000:
483 rv1 = (unsigned long)rv1 <= (unsigned long)rv2;
484 break;
485 case GEQ | UNSMARK0x1000:
486 rv1 = (unsigned long)rv1 >= (unsigned long)rv2;
487 break;
488 case LT | UNSMARK0x1000:
489 rv1 = (unsigned long)rv1 < (unsigned long)rv2;
490 break;
491 case GT | UNSMARK0x1000:
492 rv1 = (unsigned long)rv1 > (unsigned long)rv2;
493 break;
494 case LSH:
495 rv1 <<= rv2;
496 break;
497 case LSH | UNSMARK0x1000:
498 rv1 = (unsigned long) rv1 << rv2;
499 break;
500 case RSH:
501 rv1 >>= rv2;
502 break;
503 case RSH | UNSMARK0x1000:
504 rv1 = (unsigned long) rv1 >> rv2;
505 break;
506 case LAND:
507 rtype = UND2;
508 if (v1.type == UND2)
509 break;
510 if (rv1 != 0)
511 {
512 if (v2.type == UND2)
513 break;
514 rv1 = rv2 != 0;
515 }
516 else
517 rv1 = 0;
518 rtype = SGN0;
519 break;
520 case LOR:
521 rtype = UND2;
522 if (v1.type == UND2)
523 break;
524 if (rv1 == 0)
525 {
526 if (v2.type == UND2)
527 break;
528 rv1 = rv2 != 0;
529 }
530 else
531 rv1 = 1;
532 rtype = SGN0;
533 break;
534 case AND:
535 rv1 &= rv2;
536 break;
537 case STAR:
538 rv1 *= rv2;
539 break;
540 case PLUS:
541 rv1 += rv2;
542 break;
543 case MINUS:
544 rv1 -= rv2;
545 break;
546 case UMINUS:
547 if (v1.type == UND2)
548 rtype = UND2;
549 rv1 = -rv1;
550 break;
551 case OR:
552 rv1 |= rv2;
553 break;
554 case CIRC:
555 rv1 ^= rv2;
556 break;
557 case TILDE:
558 rv1 = ~rv1;
559 break;
560 case NOT:
561 rv1 = !rv1;
562 if (rtype != UND2)
563 rtype = SGN0;
564 break;
565 case SLASH:
566 if (rv2 == 0)
567 {
568 rtype = UND2;
569 break;
570 }
571 if (rtype == UNS1)
572 rv1 /= (unsigned long) rv2;
573 else
574 rv1 /= rv2;
575 break;
576 case PCT:
577 if (rv2 == 0)
578 {
579 rtype = UND2;
580 break;
581 }
582 if (rtype == UNS1)
583 rv1 %= (unsigned long) rv2;
584 else
585 rv1 %= rv2;
586 break;
587 case COLON:
588 if (op[-1] != QUEST)
18
Taking false branch
589 error(ERROR, "Bad ?: in #if/endif");
590 else
591 {
592 op--;
593 if ((--vp)->val == 0)
19
Taking true branch
594 v1 = v2;
595 rtype = v1.type;
596 rv1 = v1.val;
597 }
598 break;
20
Execution continues on line 609
599
600 case DEFINED:
601 case ARCHITECTURE:
602 break;
6
Execution continues on line 609
12
Execution continues on line 609
603
604 default:
605 error(ERROR, "Eval botch (unknown operator)");
606 return 1;
607 }
608/*lint +e574 +e644 */
609 v1.val = rv1;
610 v1.type = rtype;
611 *vp++ = v1;
612 }
613 return 0;
614}
615
616struct value
617 tokval(Token * tp)
618{
619 struct value v;
620 Nlist *np;
621 int i, base;
622 unsigned long n;
623 uchar *p, c;
624
625 v.type = SGN0;
626 v.val = 0;
627 switch (tp->type)
628 {
629
630 case NAME:
631 v.val = 0;
632 break;
633
634 case NAME1:
635 if ((np = lookup(tp, 0)) != NULL((void*)0) && np->flag & (ISDEFINED0x01 | ISMAC0x08))
636 v.val = 1;
637 break;
638
639 case NAME2:
640 if ((np = lookup(tp, 0)) != NULL((void*)0) && np->flag & (ISARCHITECTURE0x10))
641 v.val = 1;
642 break;
643
644 case NUMBER:
645 n = 0;
646 base = 10;
647 p = tp->t;
648 c = p[tp->len];
649 p[tp->len] = '\0';
650 if (*p == '0')
651 {
652 base = 8;
653 if (p[1] == 'x' || p[1] == 'X')
654 {
655 base = 16;
656 p++;
657 }
658 p++;
659 }
660 for (;; p++)
661 {
662 if ((i = digit(*p)) < 0)
663 break;
664 if (i >= base)
665 error(WARNING,
666 "Bad digit in number %t", tp);
667 n *= base;
668 n += i;
669 }
670 if (n >= 0x80000000 && base != 10)
671 v.type = UNS1;
672 for (; *p; p++)
673 {
674 if (*p == 'u' || *p == 'U')
675 v.type = UNS1;
676 else
677 if (*p == 'l' || *p == 'L')
678 ;
679 else
680 {
681 error(ERROR,
682 "Bad number %t in #if/#elsif", tp);
683 break;
684 }
685 }
686 v.val = n;
687 tp->t[tp->len] = c;
688 break;
689
690 case CCON:
691 n = 0;
692 p = tp->t;
693 if (*p == 'L')
694 {
695 p += 1;
696 error(WARNING, "Wide char constant value undefined");
697 }
698 p += 1;
699 if (*p == '\\')
700 {
701 p += 1;
702 if ((i = digit(*p)) >= 0 && i <= 7)
703 {
704 n = i;
705 p += 1;
706 if ((i = digit(*p)) >= 0 && i <= 7)
707 {
708 p += 1;
709 n <<= 3;
710 n += i;
711 if ((i = digit(*p)) >= 0 && i <= 7)
712 {
713 p += 1;
714 n <<= 3;
715 n += i;
716 }
717 }
718 }
719 else
720 if (*p == 'x')
721 {
722 p += 1;
723 while ((i = digit(*p)) >= 0 && i <= 15)
724 {
725 p += 1;
726 n <<= 4;
727 n += i;
728 }
729 }
730 else
731 {
732 static char cvcon[] = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\";
733 static size_t cvlen = sizeof(cvcon) - 1;
734
735 size_t j;
736 for (j = 0; j < cvlen; j += 2)
737 {
738 if (*p == cvcon[j])
739 {
740 n = cvcon[j + 1];
741 break;
742 }
743 }
744 p += 1;
745 if (j >= cvlen)
746 error(WARNING,
747 "Undefined escape in character constant");
748 }
749 }
750 else
751 if (*p == '\'')
752 error(ERROR, "Empty character constant");
753 else
754 n = *p++;
755 if (*p != '\'')
756 error(WARNING, "Multibyte character constant undefined");
757 else
758 if (n > 127)
759 error(WARNING, "Character constant taken as not signed");
760 v.val = n;
761 break;
762
763 case STRING:
764 error(ERROR, "String in #if/#elsif");
765 break;
766 }
767 return v;
768}
769
770int
771 digit(int i)
772{
773 if ('0' <= i && i <= '9')
774 i -= '0';
775 else
776 if ('a' <= i && i <= 'f')
777 i -= 'a' - 10;
778 else
779 if ('A' <= i && i <= 'F')
780 i -= 'A' - 10;
781 else
782 i = -1;
783 return i;
784}
785
786/* vim:set shiftwidth=4 softtabstop=4 expandtab: */