Bug Summary

File:lexer.c
Warning:line 122, column 13
Although the value stored to 'type' is used in the enclosing expression, the value is never actually read from 'type'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name lexer.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/src -resource-dir /usr/lib/llvm-14/lib/clang/14.0.6 -D HAVE_CONFIG_H -I . -I .. -D VERSION="1.25.0" -D LOCALE_DIR="/usr/local/share/locale" -D GETTEXT_PACKAGE="cafe-calc" -I /usr/include/ctk-3.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/ctk-3.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cairo -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/pango-1.0 -I /usr/include/fribidi -I /usr/include/harfbuzz -I /usr/include/atk-1.0 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/uuid -I /usr/include/freetype2 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/libpng16 -I /usr/include/x86_64-linux-gnu -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/libxml2 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.6/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/src -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-08-14-155523-14204-1 -x c lexer.c
1#include <stdlib.h>
2#include <assert.h>
3#include <string.h>
4
5#include "lexer.h"
6#include "parserfunc.h"
7#include "mp-equation.h"
8
9static gboolean
10l_check_if_function(LexerState* state)
11{
12 gchar* name = pl_get_marked_substring(state->prelexer);
13 if(!state->parent->function_is_defined)
14 {
15 free(name);
16 return FALSE(0);
17 }
18 if ((*(state->parent->function_is_defined))(state->parent, name))
19 {
20 free(name);
21 return TRUE(!(0));
22 }
23 else
24 {
25 free(name);
26 return FALSE(0);
27 }
28}
29
30static gboolean
31l_check_if_number(LexerState* state)
32{
33 MPNumber tmp;
34 int count = 0;
35 gchar* text = pl_get_marked_substring(state->prelexer);
36 if(mp_set_from_string(text, state->parent->options->base, &tmp) == 0)
37 {
38 free(text);
39 return TRUE(!(0));
40 }
41 else
42 {
43 /* Try to rollback several characters to see, if that yeilds any number. */
44 while(strlen (text) > 0)
45 {
46 if(mp_set_from_string(text, state->parent->options->base, &tmp) == 0)
47 {
48 free(text);
49 return TRUE(!(0));
50 }
51 free(text);
52 count++;
53 pl_roll_back(state->prelexer);
54 text = pl_get_marked_substring(state->prelexer);
55 }
56 /* Undo all rollbacks. */
57 while(count--)
58 pl_get_next_token (state->prelexer);
59 free(text);
60 return FALSE(0);
61 }
62}
63
64/* Insert generated token to the LexerState structure. */
65static LexerToken*
66l_insert_token(LexerState* state, const LexerTokenType type)
67{
68 state->tokens = (LexerToken *) realloc(state->tokens, (state->token_count + 1) * sizeof(LexerToken));
69 assert(state->tokens != NULL)((void) sizeof ((state->tokens != ((void*)0)) ? 1 : 0), __extension__
({ if (state->tokens != ((void*)0)) ; else __assert_fail (
"state->tokens != NULL", "lexer.c", 69, __extension__ __PRETTY_FUNCTION__
); }))
;
70 state->tokens[state->token_count].string = pl_get_marked_substring(state->prelexer);
71 state->tokens[state->token_count].start_index = state->prelexer->mark_index;
72 state->tokens[state->token_count].end_index = state->prelexer->next_index;
73 state->tokens[state->token_count].token_type = type;
74 state->token_count++;
75 return &state->tokens[state->token_count - 1];
76}
77
78/* Generates next token from pre-lexer stream and call l_insert_token() to insert it at the end. */
79static LexerToken*
80l_insert_next_token(LexerState* lstate)
81{
82 PreLexerState* state = lstate->prelexer;
83 LexerTokenType type;
84 gchar* tmp;
85 pl_set_marker(state);
86 /* Ignore all blank spaces. :) */
87 while((type = pl_get_next_token(state)) == PL_SKIP)
88 /* Set marker. Beginning of new token. */
89 pl_set_marker(state);
90 if(type == T_AND
91 ||type == T_OR
92 ||type == T_XOR
93 ||type == T_NOT
94 ||type == T_ADD
95 ||type == T_SUBTRACT
96 ||type == T_MULTIPLY
97 ||type == T_DIV
98 ||type == T_L_FLOOR
99 ||type == T_R_FLOOR
100 ||type == T_L_CEILING
101 ||type == T_R_CEILING
102 ||type == T_ROOT
103 ||type == T_ROOT_3
104 ||type == T_ROOT_4
105 ||type == T_ASSIGN
106 ||type == T_L_R_BRACKET
107 ||type == T_R_R_BRACKET
108 ||type == T_L_S_BRACKET
109 ||type == T_R_S_BRACKET
110 ||type == T_L_C_BRACKET
111 ||type == T_R_C_BRACKET
112 ||type == T_ABS
113 ||type == T_POWER
114 ||type == T_FACTORIAL
115 ||type == T_PERCENTAGE)
116 {
117 return l_insert_token(lstate, type);
118 }
119 /* [PL_SUPER_MINUS][PL_SUPER_DIGIT]+ */
120 if(type == PL_SUPER_MINUS)
121 {
122 if((type = pl_get_next_token(state)) != PL_SUPER_DIGIT)
Although the value stored to 'type' is used in the enclosing expression, the value is never actually read from 'type'
123 {
124 /* ERROR: expected PL_SUP_DIGIT */
125 set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring (state));
126 free(tmp);
127 return l_insert_token(lstate, T_UNKNOWN);
128 }
129 /* Get all PL_SUPER_DIGITs. */
130 while (pl_get_next_token(state) == PL_SUPER_DIGIT);
131 pl_roll_back(state);
132 return l_insert_token(lstate, T_NSUP_NUMBER);
133 }
134 /* [PL_SUPER_DIGIT]+ */
135 if(type == PL_SUPER_DIGIT)
136 {
137 while(pl_get_next_token(state) == PL_SUPER_DIGIT);
138 pl_roll_back(state);
139 return l_insert_token(lstate, T_SUP_NUMBER);
140 }
141 /* [PL_SUB_DIGIT]+ */
142 if(type == PL_SUB_DIGIT)
143 {
144 while(pl_get_next_token(state) == PL_SUB_DIGIT);
145 pl_roll_back(state);
146 return l_insert_token(lstate, T_SUB_NUMBER);
147 }
148 /* [PL_FRACTION] */
149 if(type == PL_FRACTION)
150 {
151 return l_insert_token(lstate, T_NUMBER);
152 }
153 if(type == PL_DIGIT)
154 {
155 while((type = pl_get_next_token(state)) == PL_DIGIT);
156 if(type == PL_FRACTION)
157 {
158 return l_insert_token(lstate, T_NUMBER);
159 }
160 else if(type == PL_SUB_DIGIT)
161 {
162 while(pl_get_next_token(state) == PL_SUB_DIGIT);
163 pl_roll_back(state);
164 return l_insert_token(lstate, T_NUMBER);
165 }
166 else if(type == PL_DEGREE)
167 {
168 type = pl_get_next_token(state);
169 if(type == PL_DIGIT)
170 {
171 while((type = pl_get_next_token(state)) == PL_DIGIT);
172 if(type == PL_DECIMAL)
173 {
174 goto ANGLE_NUM_DM_STATE;
175 }
176 else if(type == PL_MINUTE)
177 {
178 type = pl_get_next_token(state);
179 if(type == PL_DIGIT)
180 {
181 while((type = pl_get_next_token(state)) == PL_DIGIT);
182 if(type == PL_DECIMAL)
183 {
184 goto ANGLE_NUM_DMS_STATE;
185 }
186 else if(type == PL_SECOND)
187 {
188 return l_insert_token(lstate, T_NUMBER);
189 }
190 else
191 {
192 /* ERROR: expected PL_SECOND */
193 set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring (state));
194 free(tmp);
195 return l_insert_token(lstate, T_UNKNOWN);
196 }
197 }
198 else if(type == PL_DECIMAL)
199 {
200ANGLE_NUM_DMS_STATE:
201 if((type = pl_get_next_token (state)) != PL_DIGIT)
202 {
203 /* ERROR: expected PL_DIGIT */
204 set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
205 free(tmp);
206 return l_insert_token(lstate, T_UNKNOWN);
207 }
208 while((type = pl_get_next_token(state)) == PL_DIGIT);
209 if(type == PL_SECOND)
210 {
211 return l_insert_token(lstate, T_NUMBER);
212 }
213 else
214 {
215 /* ERROR: expected PL_SECOND */
216 set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
217 free(tmp);
218 return l_insert_token(lstate, T_UNKNOWN);
219 }
220 }
221 else
222 {
223 pl_roll_back(state);
224 return l_insert_token(lstate, T_NUMBER);
225 }
226 }
227 else
228 {
229 /* ERROR: expected PL_MINUTE | PL_DIGIT */
230 set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
231 free(tmp);
232 return l_insert_token(lstate, T_UNKNOWN);
233 }
234 }
235 else if(type == PL_DECIMAL)
236 {
237ANGLE_NUM_DM_STATE:
238 if((type = pl_get_next_token(state)) != PL_DIGIT)
239 {
240 /* ERROR: expected PL_DIGIT */
241 set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
242 free(tmp);
243 return l_insert_token(lstate, T_UNKNOWN);
244 }
245 while((type = pl_get_next_token(state)) == PL_DIGIT);
246 if(type == PL_MINUTE)
247 {
248 return l_insert_token(lstate, T_NUMBER);
249 }
250 else
251 {
252 /* ERROR: expected PL_MINUTE */
253 set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
254 free(tmp);
255 return l_insert_token(lstate, T_UNKNOWN);
256 }
257 }
258 else
259 {
260 return l_insert_token(lstate, T_NUMBER);
261 }
262 }
263 else if(type == PL_DECIMAL)
264 {
265 goto DECIMAL_STATE;
266 }
267 else if(type == PL_HEX)
268 {
269 goto HEX_DEC_STATE;
270 }
271 else
272 {
273 pl_roll_back(state);
274 return l_insert_token(lstate, T_NUMBER);
275 }
276 }
277 if(type == PL_DECIMAL)
278 {
279DECIMAL_STATE:
280 type = pl_get_next_token(state);
281 if(type == PL_DIGIT)
282 {
283 while((type = pl_get_next_token(state)) == PL_DIGIT);
284 if(type == PL_DEGREE)
285 {
286 return l_insert_token(lstate, T_NUMBER);
287 }
288 else if(type == PL_HEX)
289 {
290 goto DECIMAL_HEX_STATE;
291 }
292 else if(type == PL_SUB_DIGIT)
293 {
294 while(pl_get_next_token(state) == PL_SUB_DIGIT);
295 pl_roll_back(state);
296 return l_insert_token(lstate, T_NUMBER);
297 }
298 else
299 {
300 pl_roll_back(state);
301 return l_insert_token(lstate, T_NUMBER);
302 }
303 }
304 else if(type == PL_HEX)
305 {
306 goto DECIMAL_HEX_STATE;
307 }
308 else
309 {
310 /* ERROR: expected PL_DIGIT | PL_HEX */
311 set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
312 free(tmp);
313 return l_insert_token(lstate, T_UNKNOWN);
314 }
315 }
316 if(type == PL_HEX)
317 {
318 while((type = pl_get_next_token(state)) == PL_HEX);
319 if(type == PL_DIGIT)
320 {
321HEX_DEC_STATE:
322 while(1)
323 {
324 type = pl_get_next_token(state);
325 if(type == PL_DIGIT || type == PL_HEX)
326 {
327 continue;
328 }
329 else if(type == PL_DECIMAL)
330 {
331 goto DECIMAL_HEX_STATE;
332 }
333 else if(type == PL_SUB_DIGIT)
334 {
335 while(pl_get_next_token(state) == PL_SUB_DIGIT);
336 pl_roll_back(state);
337 return l_insert_token(lstate, T_NUMBER);
338 }
339 else
340 {
341 if(l_check_if_number(lstate))
342 return l_insert_token(lstate, T_NUMBER);
343 /* ERROR: expected PL_DECIMAL | PL_DIGIT | PL_HEX */
344 set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
345 free(tmp);
346 return l_insert_token(lstate, T_UNKNOWN);
347 }
348 }
349 }
350 else if(type == PL_DECIMAL)
351 {
352DECIMAL_HEX_STATE:
353 type = pl_get_next_token(state);
354 if(!(type == PL_DIGIT || type == PL_HEX))
355 {
356 /* ERROR: expected PL_DIGIT | PL_HEX */
357 set_error(lstate->parent, PARSER_ERR_MP, tmp = pl_get_marked_substring(state));
358 free(tmp);
359 return l_insert_token(lstate, T_UNKNOWN);
360 }
361 while(1)
362 {
363 type = pl_get_next_token(state);
364 if(type == PL_DIGIT || type == PL_HEX)
365 {
366 continue;
367 }
368 else if(type == PL_SUB_DIGIT)
369 {
370 while(pl_get_next_token(state) == PL_SUB_DIGIT);
371 pl_roll_back(state);
372 return l_insert_token(lstate, T_NUMBER);
373 }
374 else
375 {
376 pl_roll_back(state);
377 return l_insert_token(lstate, T_NUMBER);
378 }
379 }
380 }
381 else if(type == PL_SUB_DIGIT)
382 {
383 while(pl_get_next_token(state) == PL_SUB_DIGIT);
384 pl_roll_back(state);
385 if(l_check_if_number(lstate))
386 {
387 /* NUMBER */
388 return l_insert_token(lstate, T_NUMBER);
389 }
390 else
391 {
392 /* VARIABLE */
393 if(l_check_if_function(lstate))
394 {
395 return l_insert_token(lstate, T_FUNCTION);
396 }
397 else
398 {
399 return l_insert_token(lstate, T_VARIABLE);
400 }
401 }
402 }
403 else if(type == PL_LETTER)
404 {
405 goto LETTER_STATE;
406 }
407 else
408 {
409 pl_roll_back(state);
410 if(l_check_if_number(lstate))
411 {
412 /* NUMBER */
413 return l_insert_token(lstate, T_NUMBER);
414 }
415 else
416 {
417 /* VARIABLE */
418 if(l_check_if_function(lstate))
419 {
420 return l_insert_token(lstate, T_FUNCTION);
421 }
422 else
423 {
424 return l_insert_token(lstate, T_VARIABLE);
425 }
426 }
427 }
428 }
429 if(type == PL_LETTER)
430 {
431LETTER_STATE:
432 while(1)
433 {
434 type = pl_get_next_token(state);
435 if(type == PL_LETTER || type == PL_HEX)
436 {
437 continue;
438 }
439 else if(type == PL_SUB_DIGIT)
440 {
441 while(pl_get_next_token(state) == PL_SUB_DIGIT);
442 pl_roll_back(state);
443 tmp = g_ascii_strdown(pl_get_marked_substring(state), -1);
444 if(g_strcmp0(tmp, "mod") == 0)
445 {
446 return l_insert_token(lstate, T_MOD);
447 }
448 if(g_strcmp0(tmp, "and") == 0)
449 {
450 return l_insert_token(lstate, T_AND);
451 }
452 if(g_strcmp0(tmp, "or") == 0)
453 {
454 return l_insert_token(lstate, T_OR);
455 }
456 if(g_strcmp0(tmp, "xor") == 0)
457 {
458 return l_insert_token(lstate, T_XOR);
459 }
460 if(g_strcmp0(tmp, "not") == 0)
461 {
462 return l_insert_token(lstate, T_NOT);
463 }
464 if(g_strcmp0(tmp, "in") == 0)
465 {
466 return l_insert_token(lstate, T_IN);
467 }
468 if(l_check_if_function(lstate))
469 {
470 return l_insert_token(lstate, T_FUNCTION);
471 }
472 else
473 {
474 return l_insert_token(lstate, T_VARIABLE);
475 }
476 }
477 else
478 {
479 pl_roll_back(state);
480 tmp = g_ascii_strdown(pl_get_marked_substring(state), -1);
481 if(g_strcmp0(tmp, "mod") == 0)
482 {
483 return l_insert_token(lstate, T_MOD);
484 }
485 if(g_strcmp0(tmp, "and") == 0)
486 {
487 return l_insert_token(lstate, T_AND);
488 }
489 if(g_strcmp0(tmp, "or") == 0)
490 {
491 return l_insert_token(lstate, T_OR);
492 }
493 if(g_strcmp0(tmp, "xor") == 0)
494 {
495 return l_insert_token(lstate, T_XOR);
496 }
497 if(g_strcmp0(tmp, "not") == 0)
498 {
499 return l_insert_token(lstate, T_NOT);
500 }
501 if(g_strcmp0(tmp, "in") == 0)
502 {
503 return l_insert_token(lstate, T_IN);
504 }
505 if(l_check_if_function(lstate))
506 {
507 return l_insert_token(lstate, T_FUNCTION);
508 }
509 else
510 {
511 return l_insert_token(lstate, T_VARIABLE);
512 }
513 }
514 }
515 }
516 if(type == PL_EOS)
517 {
518 return l_insert_token(lstate, PL_EOS);
519 }
520 /* ERROR: Unexpected token.. X( */
521 set_error(lstate->parent, PARSER_ERR_INVALID, tmp = pl_get_marked_substring(state));
522 free(tmp);
523 return l_insert_token(lstate, T_UNKNOWN);
524}
525
526/* Call l_insert_next_token() as many times as needed to completely tokenize the string. */
527void
528l_insert_all_tokens(LexerState* state)
529{
530 LexerToken* token;
531 while(1)
532 {
533 token = l_insert_next_token(state);
534 assert(token != NULL)((void) sizeof ((token != ((void*)0)) ? 1 : 0), __extension__
({ if (token != ((void*)0)) ; else __assert_fail ("token != NULL"
, "lexer.c", 534, __extension__ __PRETTY_FUNCTION__); }))
;
535 if(token->token_type == PL_EOS)
536 {
537 break;
538 }
539 }
540}
541
542/* Create a lexer state from given input string. This will take care of pre-lexer state. */
543LexerState*
544l_create_lexer(const gchar* input, struct parser_state* parent)
545{
546 LexerState* ret;
547 ret = (LexerState *) malloc(sizeof(LexerState));
548 assert(ret != NULL)((void) sizeof ((ret != ((void*)0)) ? 1 : 0), __extension__ (
{ if (ret != ((void*)0)) ; else __assert_fail ("ret != NULL",
"lexer.c", 548, __extension__ __PRETTY_FUNCTION__); }))
;
549 ret->prelexer = pl_create_scanner(input);
550 ret->tokens = NULL((void*)0);
551 ret->token_count = 0;
552 ret->next_token = 0;
553 ret->parent = parent;
554 return ret;
555}
556
557/* Destroy lexer state and free memory. */
558void
559l_destroy_lexer(LexerState* state)
560{
561 int l;
562 pl_destroy_scanner(state->prelexer);
563 for(l = 0; l < state->token_count; l++)
564 {
565 free(state->tokens[l].string);
566 }
567 free(state->tokens);
568 free(state);
569}
570
571/* Get next token interface. Will be called by parser to get pointer to next token in token stream. */
572LexerToken*
573l_get_next_token(LexerState* state)
574{
575 /* Return PL_EOS token after token stream reaches to its end. */
576 if(state->next_token >= state->token_count)
577 return &state->tokens[state->token_count - 1];
578 return &state->tokens[state->next_token++];
579}
580
581/* Roll back one lexer token. */
582void
583l_roll_back(LexerState* state)
584{
585 if(state->next_token > 0)
586 state->next_token--;
587}