Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright Contributors to the OpenVDB Project | ||
2 | // SPDX-License-Identifier: MPL-2.0 | ||
3 | |||
4 | #include <openvdb_ax/compiler/Compiler.h> | ||
5 | #include <openvdb_ax/Exceptions.h> | ||
6 | |||
7 | #include "../util.h" | ||
8 | |||
9 | #include <string> | ||
10 | #include <vector> | ||
11 | #include <unordered_map> | ||
12 | #include <functional> | ||
13 | |||
14 | #include <cppunit/extensions/HelperMacros.h> | ||
15 | |||
16 | namespace { | ||
17 | |||
18 | // mimics std::pair<std::string, null> | ||
19 |
1/2✓ Branch 1 taken 504 times.
✗ Branch 2 not taken.
|
1008 | struct StrWrapper { |
20 | StrWrapper(const char* str) : first(str) {} | ||
21 | const std::string first; | ||
22 | }; | ||
23 | |||
24 | static const std::vector<StrWrapper> tests { | ||
25 | // invalid r-value syntax | ||
26 | "@a = @;", | ||
27 | "@a = =;", | ||
28 | "@a = +;", | ||
29 | "@a = -;", | ||
30 | "@a = *;", | ||
31 | "@a = /;", | ||
32 | "@a = %;", | ||
33 | "@a = |;", | ||
34 | "@a = &;", | ||
35 | "@a = ^;", | ||
36 | "@a = ~;", | ||
37 | "@a = ==;", | ||
38 | "@a = !=;", | ||
39 | "@a = >;", | ||
40 | "@a = <;", | ||
41 | "@a = >=;", | ||
42 | "@a = <=;", | ||
43 | "@a = +=;", | ||
44 | "@a = -=;", | ||
45 | "@a = *=;", | ||
46 | "@a = /=;", | ||
47 | "@a = ++;", | ||
48 | "@a = --;", | ||
49 | "@a = &&;", | ||
50 | "@a = ||;", | ||
51 | "@a = !;", | ||
52 | "@a = ,;", | ||
53 | "@a = (;", | ||
54 | "@a = );", | ||
55 | "@a = {;", | ||
56 | "@a =};", | ||
57 | "@a = .x;", | ||
58 | "@a = .y;", | ||
59 | "@a = .z;", | ||
60 | "@a = .r;", | ||
61 | "@a = .g;", | ||
62 | "@a = .b;", | ||
63 | "@a = f@;", | ||
64 | "@a = i@;", | ||
65 | "@a = v@;", | ||
66 | "@a = s@;", | ||
67 | "@a = if;", | ||
68 | "@a = else;", | ||
69 | "@a = return;", | ||
70 | "@a = ;", | ||
71 | "@a = {};", | ||
72 | "@a = \"a;", | ||
73 | "v@a.a = 0;", | ||
74 | |||
75 | "$a = $;", | ||
76 | "$a = =;", | ||
77 | "$a = +;", | ||
78 | "$a = -;", | ||
79 | "$a = *;", | ||
80 | "$a = /;", | ||
81 | "$a = %;", | ||
82 | "$a = |;", | ||
83 | "$a = &;", | ||
84 | "$a = ^;", | ||
85 | "$a = ~;", | ||
86 | "$a = ==;", | ||
87 | "$a = !=;", | ||
88 | "$a = >;", | ||
89 | "$a = <;", | ||
90 | "$a = >=;", | ||
91 | "$a = <=;", | ||
92 | "$a = +=;", | ||
93 | "$a = -=;", | ||
94 | "$a = *=;", | ||
95 | "$a = /=;", | ||
96 | "$a = ++;", | ||
97 | "$a = --;", | ||
98 | "$a = &&;", | ||
99 | "$a = ||;", | ||
100 | "$a = !;", | ||
101 | "$a = ,;", | ||
102 | "$a = (;", | ||
103 | "$a = );", | ||
104 | "$a = {;", | ||
105 | "$a =};", | ||
106 | "$a = .x;", | ||
107 | "$a = .y;", | ||
108 | "$a = .z;", | ||
109 | "$a = .r;", | ||
110 | "$a = .g;", | ||
111 | "$a = .b;", | ||
112 | "$a = f$;", | ||
113 | "$a = i$;", | ||
114 | "$a = v$;", | ||
115 | "$a = s$;", | ||
116 | "$a = if;", | ||
117 | "$a = else;", | ||
118 | "$a = return;", | ||
119 | "$a = ;", | ||
120 | "$a = {};", | ||
121 | "$a = {1};", | ||
122 | "$a = \"a;", | ||
123 | "v$a[0] = 0;", | ||
124 | "v$a.a = 0;", | ||
125 | |||
126 | // @todo these should probably be valid syntax and the code | ||
127 | // generators should handle assignments based on the current | ||
128 | // r/lvalues | ||
129 | "5 = 5;", | ||
130 | "$a = 5;", | ||
131 | |||
132 | // invalid l-value | ||
133 | // TODO: these should fail syntax tests | ||
134 | // {"+@a = 0;", }, | ||
135 | // {"-@a = 0;", }, | ||
136 | // {"~@a = 0;", }, | ||
137 | // {"!@a = 0;", }, | ||
138 | // "++@a = 0;", | ||
139 | // "--@a = 0;", | ||
140 | "=@a;", | ||
141 | "*@a;", | ||
142 | "/@a;", | ||
143 | "%@a;", | ||
144 | "|@a;", | ||
145 | "&@a;", | ||
146 | "^@a;", | ||
147 | "==@a;", | ||
148 | "!=@a;", | ||
149 | ">@a;", | ||
150 | "<@a;", | ||
151 | ">=@a;", | ||
152 | "<=@a;", | ||
153 | "+=@a;", | ||
154 | "-=@a;", | ||
155 | "*=@a;", | ||
156 | "/=@a;", | ||
157 | "&&@a;", | ||
158 | "||@a;", | ||
159 | ",@a;", | ||
160 | "(@a;", | ||
161 | ")@a;", | ||
162 | "{@a;", | ||
163 | "}@a;", | ||
164 | ".x@a;", | ||
165 | ".y@a;", | ||
166 | ".z@a;", | ||
167 | ".r@a;", | ||
168 | ".g@a;", | ||
169 | ".b@a;", | ||
170 | "@@a;", | ||
171 | "f@@a;", | ||
172 | "i@@a;", | ||
173 | "v@@a;", | ||
174 | "s@@a;", | ||
175 | "if@a;", | ||
176 | "else@a;", | ||
177 | "return@a;", | ||
178 | "{1}@a;", | ||
179 | "\"a\"@a;", | ||
180 | "b@a;", | ||
181 | "sht@a;", | ||
182 | "it@a;", | ||
183 | "l@a;", | ||
184 | "flt@a;", | ||
185 | "dbl@a;", | ||
186 | "vecint@a;", | ||
187 | "vint@a;", | ||
188 | "vfloat@a;", | ||
189 | "vecflt@a;", | ||
190 | "vflt@a;", | ||
191 | "vdouble@a;", | ||
192 | "vecdbl@a;", | ||
193 | "vdbl@a;", | ||
194 | "str@a;", | ||
195 | |||
196 | "++$a = 0;", | ||
197 | "--$a = 0;", | ||
198 | "=$a;", | ||
199 | "*$a;", | ||
200 | "/$a;", | ||
201 | "%$a;", | ||
202 | "|$a;", | ||
203 | "&$a;", | ||
204 | "^$a;", | ||
205 | "==$a;", | ||
206 | "!=$a;", | ||
207 | ">$a;", | ||
208 | "<$a;", | ||
209 | ">=$a;", | ||
210 | "<=$a;", | ||
211 | "+=$a;", | ||
212 | "-=$a;", | ||
213 | "*=$a;", | ||
214 | "/=$a;", | ||
215 | "&&$a;", | ||
216 | "||$a;", | ||
217 | ",$a;", | ||
218 | "($a;", | ||
219 | ")$a;", | ||
220 | "{$a;", | ||
221 | "}$a;", | ||
222 | ".x$a;", | ||
223 | ".y$a;", | ||
224 | ".z$a;", | ||
225 | ".r$a;", | ||
226 | ".g$a;", | ||
227 | ".b$a;", | ||
228 | "$$a;", | ||
229 | "f$$a;", | ||
230 | "i$$a;", | ||
231 | "v$$a;", | ||
232 | "s$$a;", | ||
233 | "if$a;", | ||
234 | "else$a;", | ||
235 | "return$a;", | ||
236 | "{1}$a;", | ||
237 | "\"a\"$a;", | ||
238 | "b$a;", | ||
239 | "sht$a;", | ||
240 | "it$a;", | ||
241 | "l$a;", | ||
242 | "flt$a;", | ||
243 | "dbl$a;", | ||
244 | "vecint$a;", | ||
245 | "vint$a;", | ||
246 | "vfloat$a;", | ||
247 | "vecflt$a;", | ||
248 | "vflt$a;", | ||
249 | "vdouble$a;", | ||
250 | "vecdbl$a;", | ||
251 | "vdbl$a;", | ||
252 | "str$a;", | ||
253 | |||
254 | "a ! a;", | ||
255 | "a ~ a;", | ||
256 | "a \\ a;", | ||
257 | "a ? a;", | ||
258 | "bool + a;", | ||
259 | "bool a + a;", | ||
260 | "return + a;", | ||
261 | "if + a;", | ||
262 | "a + if(true) {};", | ||
263 | "{} + {};", | ||
264 | "{} int", | ||
265 | "~ + !;", | ||
266 | "+ + -;", | ||
267 | "; + ;", | ||
268 | "int();", | ||
269 | "int(return);", | ||
270 | "int(if(true) {});", | ||
271 | "int(;);", | ||
272 | "int(bool a;);", | ||
273 | "int(bool a);", | ||
274 | "int{a};", | ||
275 | "int[a];", | ||
276 | "string(a);", | ||
277 | "vector(a);", | ||
278 | "vec3i(a);", | ||
279 | "vec3f(a);", | ||
280 | "vec3d(a);", | ||
281 | |||
282 | // invalid if block | ||
283 | "if (a) {b}", | ||
284 | "if (a) else ();", | ||
285 | "if (); else (a);", | ||
286 | "if (a) if(b) {if (c)} else {}", | ||
287 | "if (if(a));", | ||
288 | "if ();", | ||
289 | "if (); else ;", | ||
290 | "if (); else ();", | ||
291 | "if (); else () {}", | ||
292 | "if (); elf {}", | ||
293 | "if (a) {} elif (b) {}", | ||
294 | "else {}", | ||
295 | "else ;", | ||
296 | "if a;", | ||
297 | "if a {} elif b {}", | ||
298 | "if (a); else ; else ;", | ||
299 | "else (a); ", | ||
300 | "if (a) {}; else {};", | ||
301 | "if (a) {b = 1} else {};", | ||
302 | "if (a) {} ; else {}", | ||
303 | "if () {}; else (a);", | ||
304 | |||
305 | // invalid ternary | ||
306 | "?;", | ||
307 | ":;", | ||
308 | "? :;", | ||
309 | "? : false;", | ||
310 | "true ? :;", | ||
311 | "true ? false;", | ||
312 | "true ? false :;", | ||
313 | "true : 1 ? 2;", | ||
314 | "true ? 1 ? 2;", | ||
315 | "true : 1 : 2;", | ||
316 | "true ?? 1 : 2;", | ||
317 | "true (? 1 :) 2;", | ||
318 | "true (?:) 2;", | ||
319 | "true (? false ? 1 : 2): 3;", | ||
320 | "true ? (false ? 1 : 2:) 3;", | ||
321 | "(true ? false ? 1 : 2): 3;", | ||
322 | |||
323 | // invalid crement | ||
324 | "++5;", | ||
325 | "5++;", | ||
326 | "--5;", | ||
327 | "5--;", | ||
328 | "++5--;", | ||
329 | "++5++;", | ||
330 | "--5++;", | ||
331 | "--5--;", | ||
332 | "{ 1, 1, 1}++;", | ||
333 | "++{ 1, 1, 1};", | ||
334 | "--{ 1, 1, 1};", | ||
335 | "{ 1, 1, 1}--;", | ||
336 | "++{ 1, 1, 1}++;", | ||
337 | "++{ 1, 1, 1}--;", | ||
338 | "--{ 1, 1, 1}--;", | ||
339 | "++a-;", | ||
340 | //"++a--;", | ||
341 | //"++a++;", | ||
342 | //"--a++;", | ||
343 | //"--a--;", | ||
344 | //"----a;", | ||
345 | //"++++a;", | ||
346 | //"a.x--;", | ||
347 | //"-a.y--;", | ||
348 | //"++a.z;", | ||
349 | //"++@a--;", | ||
350 | //"@a.x--;", | ||
351 | //"-@a.y--;", | ||
352 | //"++@a.z;", | ||
353 | "++$a--;", | ||
354 | "$a.x--;", | ||
355 | "-$a.y--;", | ||
356 | "++$a.z;", | ||
357 | "--f();", | ||
358 | "f()++;", | ||
359 | "return++;", | ||
360 | "--return;", | ||
361 | "true++;", | ||
362 | "--false;", | ||
363 | "--if;", | ||
364 | "if++;", | ||
365 | "else++;", | ||
366 | "--else;", | ||
367 | "--bool;", | ||
368 | "short++;", | ||
369 | "--int;", | ||
370 | "long++;", | ||
371 | "--float;", | ||
372 | "++double;", | ||
373 | "--vector;", | ||
374 | "matrix--;", | ||
375 | "--();", | ||
376 | "()++;", | ||
377 | "{}++;", | ||
378 | "--{};", | ||
379 | "--,;", | ||
380 | ",--;", | ||
381 | |||
382 | // invalid declare | ||
383 | "int;", | ||
384 | "int 1;", | ||
385 | "string int;", | ||
386 | "int bool a;", | ||
387 | "int a", | ||
388 | "vector a", | ||
389 | "vector float a", | ||
390 | |||
391 | // invalid function | ||
392 | "function(;", | ||
393 | "function);", | ||
394 | "return();", | ||
395 | "function(bool);", | ||
396 | "function(bool a);", | ||
397 | "function(+);", | ||
398 | "function(!);", | ||
399 | "function(~);", | ||
400 | "function(-);", | ||
401 | "function(&&);", | ||
402 | "function{};" , | ||
403 | "function(,);" , | ||
404 | "function(, a);", | ||
405 | "function(a, );", | ||
406 | "function({,});", | ||
407 | "function({});", | ||
408 | "function({)};", | ||
409 | "function{()};", | ||
410 | "function{(});", | ||
411 | "function{,};", | ||
412 | "function(if(true) {});", | ||
413 | "function(return);", | ||
414 | "function(return;);", | ||
415 | "function(while(true) a);", | ||
416 | "function(while(true) {});", | ||
417 | "\"function\"();" , | ||
418 | "();", | ||
419 | "+();", | ||
420 | "10();", | ||
421 | |||
422 | // invalid keyword return | ||
423 | "return", | ||
424 | "int return;", | ||
425 | "return return;", | ||
426 | "return max(1, 2);", | ||
427 | "return 1 + a;", | ||
428 | "return !a;", | ||
429 | "return a = 1;", | ||
430 | "return a.x = 1;", | ||
431 | "return ++a;", | ||
432 | "return int(a);", | ||
433 | "return {1, 2, 3};", | ||
434 | "return a[1];", | ||
435 | "return true;", | ||
436 | "return 0;", | ||
437 | "return (1);", | ||
438 | "return \"a\";", | ||
439 | "return int a;", | ||
440 | "return a;", | ||
441 | "return @a;", | ||
442 | |||
443 | // invalid unary | ||
444 | "+bool;" , | ||
445 | "+bool a;" , | ||
446 | "bool -a;" , | ||
447 | "-return;" , | ||
448 | "!return;" , | ||
449 | "+return;" , | ||
450 | "~return;" , | ||
451 | "~if(a) {};" , | ||
452 | "if(a) -{};" , | ||
453 | "if(a) {} !else {};", | ||
454 | // @todo unary crementation expressions should be parsable but perhaps | ||
455 | // not compilable | ||
456 | "---a;" , | ||
457 | "+++a;" , | ||
458 | |||
459 | // invalid value | ||
460 | ".0.0;", | ||
461 | ".0.0f;", | ||
462 | ".f;", | ||
463 | "0..0;", | ||
464 | "0.0l;", | ||
465 | "0.0ls;", | ||
466 | "0.0s;", | ||
467 | "0.0sf;", | ||
468 | "0.a", | ||
469 | "0.af", | ||
470 | "00ls;", | ||
471 | "0ef;", | ||
472 | "0f0;", | ||
473 | "1.0f.0;", | ||
474 | "1.\"1\";", | ||
475 | "1.e6f;", | ||
476 | "10000000.00000001s;", | ||
477 | "1e.6f;", | ||
478 | "1Ee6;", | ||
479 | "1ee6;", | ||
480 | "1eE6f;", | ||
481 | "1ee6f;", | ||
482 | "1l.0;", | ||
483 | "1s.0;", | ||
484 | "\"1.\"2;", | ||
485 | "a.0", | ||
486 | "a.0f", | ||
487 | "false.0;", | ||
488 | "true.;", | ||
489 | |||
490 | // invalid vector | ||
491 | "{1,2,3];", | ||
492 | "[1,2,3};", | ||
493 | "{,,};", | ||
494 | "{,2,3};", | ||
495 | "{()};", | ||
496 | "{(1,)};", | ||
497 | "{(,1)};", | ||
498 | "{(1});", | ||
499 | "({1)};", | ||
500 | "{1,};", | ||
501 | "{,1};", | ||
502 | |||
503 | // invalid vector unpack | ||
504 | "5.x;", | ||
505 | "foo.2;", | ||
506 | "a.w;", | ||
507 | "a.X;", | ||
508 | "a.Y;", | ||
509 | "a.Z;", | ||
510 | "@a.X;", | ||
511 | "@a.Y;", | ||
512 | "@a.Z;", | ||
513 | "$a.X;", | ||
514 | "$a.Y;", | ||
515 | "$a.Z;", | ||
516 | "a.xx;", | ||
517 | "a++.x", | ||
518 | "++a.x", | ||
519 | "func().x", | ||
520 | "int(y).x", | ||
521 | "vector .", | ||
522 | "vector .x", | ||
523 | "vector foo.x", | ||
524 | "(a + b).x", | ||
525 | "(a).x;", | ||
526 | "(@a).x;", | ||
527 | "@.x;", | ||
528 | "($a).x;", | ||
529 | "$.x;", | ||
530 | "true.x;", | ||
531 | "a.rx;", | ||
532 | "a.rgb;", | ||
533 | |||
534 | // other failures (which may be used in the future) | ||
535 | "function<>();", | ||
536 | "function<true>();", | ||
537 | "a[1:1];", | ||
538 | "a.a;", | ||
539 | "a->a;", | ||
540 | "&a;", | ||
541 | "a . a;", | ||
542 | "a .* a;", | ||
543 | "@a();", | ||
544 | "$a();", | ||
545 | "@a.function();", | ||
546 | "@a.member;", | ||
547 | "/**/;", | ||
548 | "(a,a,a) = (b,b,b);", | ||
549 | "(a,a,a) = 1;", | ||
550 | "(a) = 1;", | ||
551 | "a = (a=a) = a;", | ||
552 | |||
553 | // invalid lone characters | ||
554 | "£;", | ||
555 | "`;", | ||
556 | "¬;", | ||
557 | "@;", | ||
558 | "~;", | ||
559 | "+;", | ||
560 | "-;", | ||
561 | "*;", | ||
562 | "/;", | ||
563 | "<<;", | ||
564 | ">>;", | ||
565 | ">;", | ||
566 | "<;", | ||
567 | "[];", | ||
568 | "|;", | ||
569 | ",;", | ||
570 | "!;", | ||
571 | "\\;", | ||
572 | |||
573 | // Test right associativity. These symbols are defined with %right in the | ||
574 | // parser which forces partial creation of ASTs. ::parse should ensure | ||
575 | // that these cases still produce invalid AST ptrs. | ||
576 | "{} ?", | ||
577 | "{} :", | ||
578 | "{} =", | ||
579 | "{} +=", | ||
580 | "{} -=", | ||
581 | "{} /=", | ||
582 | "{} *=", | ||
583 | "{} %=", | ||
584 | "{} |=", | ||
585 | "{} &=", | ||
586 | "{} ^=", | ||
587 | "{} <<=", | ||
588 | "{} >>=" | ||
589 | }; | ||
590 | |||
591 | } | ||
592 | |||
593 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | class TestSyntaxFailures : public CppUnit::TestCase |
594 | { | ||
595 | public: | ||
596 | |||
597 |
3/6✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
4 | CPPUNIT_TEST_SUITE(TestSyntaxFailures); |
598 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
6 | CPPUNIT_TEST(testSyntax); |
599 |
4/8✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
|
4 | CPPUNIT_TEST_SUITE_END(); |
600 | |||
601 | void testSyntax(); | ||
602 | }; | ||
603 | |||
604 | CPPUNIT_TEST_SUITE_REGISTRATION(TestSyntaxFailures); | ||
605 | |||
606 | 1 | void TestSyntaxFailures::testSyntax() | |
607 | { | ||
608 | // Quickly check the above doesn't have multiple occurrence | ||
609 | // store multiple in a hash map | ||
610 | const auto hash = [](const StrWrapper* s) { | ||
611 | return std::hash<std::string>()(s->first); | ||
612 | }; | ||
613 | const auto equal = [](const StrWrapper* s1, const StrWrapper* s2) { | ||
614 | ✗ | return s1->first.compare(s2->first) == 0; | |
615 | }; | ||
616 | std::unordered_map<const StrWrapper*, | ||
617 | 1 | size_t, decltype(hash), decltype(equal)> map(tests.size(), hash, equal); | |
618 | |||
619 |
2/2✓ Branch 0 taken 504 times.
✓ Branch 1 taken 1 times.
|
505 | for (const auto& test : tests) { |
620 |
1/2✓ Branch 1 taken 504 times.
✗ Branch 2 not taken.
|
504 | ++map[&test]; |
621 | } | ||
622 | |||
623 | // Print strings that occur more than once | ||
624 |
2/2✓ Branch 0 taken 504 times.
✓ Branch 1 taken 1 times.
|
505 | for (auto iter : map) { |
625 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 504 times.
|
504 | if (iter.second > 1) { |
626 | ✗ | std::cout << iter.first->first << " printed x" << iter.second << std::endl; | |
627 | } | ||
628 | } | ||
629 | |||
630 |
19/38✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 504 times.
✓ Branch 8 taken 1 times.
✓ Branch 10 taken 504 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 504 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 504 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 504 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 504 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 504 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 504 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 504 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 504 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 504 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 504 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 504 times.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✓ Branch 45 taken 504 times.
✓ Branch 47 taken 504 times.
✗ Branch 48 not taken.
✗ Branch 60 not taken.
✓ Branch 61 taken 504 times.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
|
1515 | TEST_SYNTAX_FAILS(tests); |
631 | 1 | } | |
632 |