clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pong.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 -mthread-model posix -mframe-pointer=all -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -fno-plt -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/clang/10.0.0 -include /home/buildbot/lwan-worker/clang-analyze/build/lwan-build-config.h -D _FILE_OFFSET_BITS=64 -D _TIME_BITS=64 -I /home/buildbot/lwan-worker/clang-analyze/build/src/lib/missing -I /usr/include/luajit-2.0 -I /usr/include/valgrind -I /home/buildbot/lwan-worker/clang-analyze/build/src/lib -internal-isystem /usr/local/include -internal-isystem /usr/lib/clang/10.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -Wno-free-nonheap-object -std=gnu99 -fdebug-compilation-dir /home/buildbot/lwan-worker/clang-analyze/build/src/samples/clock -ferror-limit 19 -fmessage-length 0 -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -analyzer-output=html -faddrsig -o /home/buildbot/lwan-worker/clang-analyze/CLANG/2020-07-05-015813-1106367-1 -x c /home/buildbot/lwan-worker/clang-analyze/build/src/samples/clock/pong.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | #include <limits.h> |
26 | #include <math.h> |
27 | #include <stdlib.h> |
28 | |
29 | #include "pong.h" |
30 | |
31 | extern const uint8_t digital_clock_font[10][5]; |
32 | |
33 | static float rand_float(float scale) |
34 | { |
35 | return ((float)rand() / (float)(RAND_MAX)) * scale; |
36 | } |
37 | |
38 | static void pong_time_update(struct pong_time *pong_time) |
39 | { |
40 | time_t cur_time = time(NULL); |
41 | |
42 | if (cur_time != pong_time->last_time) { |
| 23 | | The right operand of '!=' is a garbage value |
|
43 | char digits[5]; |
44 | |
45 | strftime(digits, sizeof(digits), "%H%M", localtime(&cur_time)); |
46 | |
47 | for (int i = 0; i < 4; i++) |
48 | pong_time->time[i] = digits[i] - '0'; |
49 | |
50 | pong_time->hour = pong_time->time[0] * 10 + pong_time->time[1]; |
51 | pong_time->minute = pong_time->time[2] * 10 + pong_time->time[3]; |
52 | |
53 | pong_time->last_time = cur_time; |
54 | } |
55 | } |
56 | |
57 | void pong_init(struct pong *pong, ge_GIF *gif) |
58 | { |
59 | float ball_y = rand_float(16.0f) + 8.0f; |
60 | |
61 | *pong = (struct pong){ |
62 | .gif = gif, |
63 | .ball_x = {.pos = 31.0f, .vel = 1.0f}, |
64 | .ball_y = {.pos = ball_y, .vel = rand() % 2 ? -0.5f : 0.5f}, |
65 | .player_left = {.y = 8, .target_y = ball_y}, |
66 | .player_right = {.y = 18, .target_y = ball_y}, |
67 | .player_loss = 0, |
68 | .game_stopped = 0, |
69 | }; |
70 | |
71 | pong_time_update(&pong->time); |
72 | } |
73 | |
74 | static void draw_pixel(unsigned char *frame, int x, int y, unsigned char color) |
75 | { |
76 | if (x < 64 && y < 32) |
77 | frame[y * 64 + x] = color; |
78 | } |
79 | |
80 | static void pong_draw_net(const struct pong *pong) |
81 | { |
82 | for (int i = 1; i < 32; i += 2) |
83 | draw_pixel(pong->gif->frame, 31, i, 6); |
84 | } |
85 | |
86 | static void pong_draw_player(const struct pong *pong, int x, int y) |
87 | { |
88 | for (int i = 0; i < 2; i++) { |
89 | for (int j = 0; j < 8; j++) |
90 | draw_pixel(pong->gif->frame, x + i, y + j, 3); |
91 | } |
92 | } |
93 | |
94 | static void pong_draw_ball(const struct pong *pong) |
95 | { |
96 | int x = (int)pong->ball_x.pos; |
97 | int y = (int)pong->ball_y.pos; |
98 | |
99 | draw_pixel(pong->gif->frame, x, y, 1); |
100 | draw_pixel(pong->gif->frame, x + 1, y, 1); |
101 | draw_pixel(pong->gif->frame, x, y + 1, 1); |
102 | draw_pixel(pong->gif->frame, x + 1, y + 1, 1); |
103 | } |
104 | |
105 | static void pong_draw_time(const struct pong *pong) |
106 | { |
107 | static const uint8_t base_offsets[] = {23, 23, 25, 25}; |
108 | static const uint8_t colors[] = {0, 6}; |
109 | unsigned char *frame = pong->gif->frame; |
110 | |
111 | for (int digit = 0; digit < 4; digit++) { |
112 | int dig = pong->time.time[digit]; |
113 | uint8_t off = base_offsets[digit]; |
114 | |
115 | for (int line = 0, base = digit * 4; line < 5; line++, base += 64) { |
116 | frame[base + 0 + off] = colors[!!(digital_clock_font[dig][line] & 1<<2)]; |
117 | frame[base + 1 + off] = colors[!!(digital_clock_font[dig][line] & 1<<1)]; |
118 | frame[base + 2 + off] = colors[!!(digital_clock_font[dig][line] & 1<<0)]; |
119 | } |
120 | } |
121 | } |
122 | |
123 | static float pong_calculate_end_point(const struct pong *pong, bool hit) |
124 | { |
125 | float x = pong->ball_x.pos; |
126 | float y = pong->ball_y.pos; |
127 | float vel_x = pong->ball_x.vel; |
128 | float vel_y = pong->ball_y.vel; |
129 | |
130 | for (;;) { |
131 | x += vel_x; |
132 | y += vel_y; |
133 | if (hit) { |
134 | if (x >= 60.0f || x <= 2.0f) |
135 | return y; |
136 | } else { |
137 | if (x >= 62.0f || x <= 0.0f) |
138 | return y; |
139 | } |
140 | if (y >= 30.0f || y <= 0.0f) |
141 | vel_y = -vel_y; |
142 | } |
143 | } |
144 | |
145 | static void pong_clamp_player_pos(struct pong *pong, bool left, bool right) |
146 | { |
147 | if (left) { |
148 | if (pong->player_left.target_y < 0.0f) |
149 | pong->player_left.target_y = 0.0f; |
150 | else if (pong->player_left.target_y > 24.0f) |
151 | pong->player_left.target_y = 24.0f; |
152 | } |
153 | |
154 | if (right) { |
155 | if (pong->player_right.target_y < 0.0f) |
156 | pong->player_right.target_y = 0.0f; |
157 | else if (pong->player_right.target_y > 24.0f) |
158 | pong->player_right.target_y = 24.0f; |
159 | } |
160 | } |
161 | |
162 | uint64_t pong_draw(struct pong *pong) |
163 | { |
164 | if (pong->game_stopped < 20) { |
| 1 | Assuming field 'game_stopped' is >= 20 | |
|
| |
165 | pong->game_stopped++; |
166 | goto draw; |
167 | } |
168 | |
169 | pong->ball_x.pos += pong->ball_x.vel; |
170 | pong->ball_y.pos += pong->ball_y.vel; |
171 | |
172 | if ((pong->ball_x.pos >= 60.0f && pong->player_loss != 1) || |
| 3 | | Assuming the condition is false | |
|
173 | (pong->ball_x.pos <= 2.0f && pong->player_loss != -1)) { |
| 4 | | Assuming the condition is false | |
|
174 | pong->ball_x.vel = -pong->ball_x.vel; |
175 | if (rand() % 4 > 0) { |
176 | if (rand() % 2 == 0) { |
177 | if (pong->ball_y.vel > 0.0f && pong->ball_y.vel < 2.5f) |
178 | pong->ball_y.vel += 0.2f; |
179 | else if (pong->ball_y.vel < 0.0f && pong->ball_y.vel > -2.5f) |
180 | pong->ball_y.vel -= 0.2f; |
181 | |
182 | if (pong->ball_x.pos >= 60.0f) |
183 | pong->player_right.target_y += 1.0f + rand_float(3); |
184 | else |
185 | pong->player_left.target_y += 1.0f + rand_float(3); |
186 | } else { |
187 | if (pong->ball_y.vel > 0.5f) |
188 | pong->ball_y.vel -= 0.2f; |
189 | else if (pong->ball_y.vel < -0.5f) |
190 | pong->ball_y.vel += 0.2f; |
191 | |
192 | if (pong->ball_x.pos >= 60.0f) |
193 | pong->player_right.target_y -= 1.0f + rand_float(3); |
194 | else |
195 | pong->player_left.target_y -= 1.0f + rand_float(3); |
196 | } |
197 | |
198 | pong_clamp_player_pos(pong, true, true); |
199 | } |
200 | } else if ((pong->ball_x.pos > 62.0f && pong->player_loss == 1) || |
| 5 | | Assuming the condition is false | |
|
201 | (pong->ball_x.pos < 0.0f && pong->player_loss == -1)) { |
| 6 | | Assuming the condition is false | |
|
202 | pong_init(pong, pong->gif); |
203 | } |
204 | |
205 | if (pong->ball_y.pos >= 30.0f || pong->ball_y.pos <= 0.0f) |
| 7 | | Assuming the condition is false | |
|
| 8 | | Assuming the condition is false | |
|
| |
206 | pong->ball_y.vel = -pong->ball_y.vel; |
207 | |
208 | if (roundf(pong->ball_x.pos) == 40.0f + rand_float(13)) { |
| 10 | | Assuming the condition is false | |
|
| |
209 | pong->player_left.target_y = pong->ball_y.pos - 3.0f; |
210 | pong_clamp_player_pos(pong, true, false); |
211 | } else if (roundf(pong->ball_x.pos) == 8 + rand_float(13)) { |
| 12 | | Assuming the condition is false | |
|
| |
212 | pong->player_right.target_y = pong->ball_y.pos - 3.0f; |
213 | pong_clamp_player_pos(pong, false, true); |
214 | } |
215 | |
216 | if (pong->player_left.target_y > pong->player_left.y) |
| 14 | | Assuming field 'target_y' is <= field 'y' | |
|
| |
217 | pong->player_left.y++; |
218 | else if (pong->player_left.target_y < pong->player_left.y) |
| 16 | | Assuming field 'target_y' is >= field 'y' | |
|
| |
219 | pong->player_left.y--; |
220 | |
221 | if (pong->player_right.target_y > pong->player_right.y) |
| 18 | | Assuming field 'target_y' is > field 'y' | |
|
| |
222 | pong->player_right.y++; |
223 | else if (pong->player_right.target_y < pong->player_right.y) |
224 | pong->player_right.y--; |
225 | |
226 | |
227 | |
228 | if (roundf(pong->ball_x.pos) == 32.0f) { |
| 20 | | Assuming the condition is true | |
|
| |
229 | struct pong_time cur_time; |
230 | |
231 | pong_time_update(&cur_time); |
| 22 | | Calling 'pong_time_update' | |
|
232 | |
233 | if (cur_time.minute != pong->time.minute && pong->player_loss == 0) { |
234 | |
235 | if (cur_time.minute == 0) |
236 | pong->player_loss = 1; |
237 | else |
238 | pong->player_loss = -1; |
239 | } |
240 | |
241 | if (pong->ball_x.vel < 0) { |
242 | pong->player_left.target_y = |
243 | pong_calculate_end_point(pong, pong->player_loss != -1) - 3; |
244 | if (pong->player_loss == -1) { |
245 | if (pong->player_left.target_y < 16) |
246 | pong->player_left.target_y = 19 + rand_float(5); |
247 | else |
248 | pong->player_left.target_y = 5 + rand_float(2); |
249 | } |
250 | |
251 | pong_clamp_player_pos(pong, true, false); |
252 | } else if (pong->ball_x.vel > 0) { |
253 | pong->player_right.target_y = |
254 | pong_calculate_end_point(pong, pong->player_loss != 1) - 3; |
255 | if (pong->player_loss == 1) { |
256 | if (pong->player_right.target_y < 16) |
257 | pong->player_right.target_y = 19 + rand_float(5); |
258 | else |
259 | pong->player_right.target_y = 5 + rand_float(2); |
260 | } |
261 | |
262 | pong_clamp_player_pos(pong, false, true); |
263 | } |
264 | |
265 | if (pong->ball_y.pos < 0) |
266 | pong->ball_y.pos = 0; |
267 | else if (pong->ball_y.pos > 30) |
268 | pong->ball_y.pos = 30; |
269 | } |
270 | |
271 | draw: |
272 | memset(pong->gif->frame, 0, 64 * 32); |
273 | pong_draw_net(pong); |
274 | pong_draw_time(pong); |
275 | pong_draw_player(pong, 0, pong->player_left.y); |
276 | pong_draw_player(pong, 62, pong->player_right.y); |
277 | pong_draw_ball(pong); |
278 | |
279 | return 8; |
280 | } |