1 //
2 // Copyright 2012 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "PreprocessorTest.h"
8 #include "compiler/preprocessor/Token.h"
9 
10 namespace angle
11 {
12 
13 class IfTest : public SimplePreprocessorTest
14 {};
15 
TEST_F(IfTest,If_0)16 TEST_F(IfTest, If_0)
17 {
18     const char *str =
19         "pass_1\n"
20         "#if 0\n"
21         "fail\n"
22         "#endif\n"
23         "pass_2\n";
24     const char *expected =
25         "pass_1\n"
26         "\n"
27         "\n"
28         "\n"
29         "pass_2\n";
30 
31     preprocess(str, expected);
32 }
33 
TEST_F(IfTest,If_1)34 TEST_F(IfTest, If_1)
35 {
36     const char *str =
37         "pass_1\n"
38         "#if 1\n"
39         "pass_2\n"
40         "#endif\n"
41         "pass_3\n";
42     const char *expected =
43         "pass_1\n"
44         "\n"
45         "pass_2\n"
46         "\n"
47         "pass_3\n";
48 
49     preprocess(str, expected);
50 }
51 
TEST_F(IfTest,If_0_Else)52 TEST_F(IfTest, If_0_Else)
53 {
54     const char *str =
55         "pass_1\n"
56         "#if 0\n"
57         "fail\n"
58         "#else\n"
59         "pass_2\n"
60         "#endif\n"
61         "pass_3\n";
62     const char *expected =
63         "pass_1\n"
64         "\n"
65         "\n"
66         "\n"
67         "pass_2\n"
68         "\n"
69         "pass_3\n";
70 
71     preprocess(str, expected);
72 }
73 
TEST_F(IfTest,If_1_Else)74 TEST_F(IfTest, If_1_Else)
75 {
76     const char *str =
77         "pass_1\n"
78         "#if 1\n"
79         "pass_2\n"
80         "#else\n"
81         "fail\n"
82         "#endif\n"
83         "pass_3\n";
84     const char *expected =
85         "pass_1\n"
86         "\n"
87         "pass_2\n"
88         "\n"
89         "\n"
90         "\n"
91         "pass_3\n";
92 
93     preprocess(str, expected);
94 }
95 
TEST_F(IfTest,If_0_Elif)96 TEST_F(IfTest, If_0_Elif)
97 {
98     const char *str =
99         "pass_1\n"
100         "#if 0\n"
101         "fail_1\n"
102         "#elif 0\n"
103         "fail_2\n"
104         "#elif 1\n"
105         "pass_2\n"
106         "#elif 1\n"
107         "fail_3\n"
108         "#else\n"
109         "fail_4\n"
110         "#endif\n"
111         "pass_3\n";
112     const char *expected =
113         "pass_1\n"
114         "\n"
115         "\n"
116         "\n"
117         "\n"
118         "\n"
119         "pass_2\n"
120         "\n"
121         "\n"
122         "\n"
123         "\n"
124         "\n"
125         "pass_3\n";
126 
127     preprocess(str, expected);
128 }
129 
TEST_F(IfTest,If_1_Elif)130 TEST_F(IfTest, If_1_Elif)
131 {
132     const char *str =
133         "pass_1\n"
134         "#if 1\n"
135         "pass_2\n"
136         "#elif 0\n"
137         "fail_1\n"
138         "#elif 1\n"
139         "fail_2\n"
140         "#else\n"
141         "fail_4\n"
142         "#endif\n"
143         "pass_3\n";
144     const char *expected =
145         "pass_1\n"
146         "\n"
147         "pass_2\n"
148         "\n"
149         "\n"
150         "\n"
151         "\n"
152         "\n"
153         "\n"
154         "\n"
155         "pass_3\n";
156 
157     preprocess(str, expected);
158 }
159 
TEST_F(IfTest,If_Elif_Else)160 TEST_F(IfTest, If_Elif_Else)
161 {
162     const char *str =
163         "pass_1\n"
164         "#if 0\n"
165         "fail_1\n"
166         "#elif 0\n"
167         "fail_2\n"
168         "#elif 0\n"
169         "fail_3\n"
170         "#else\n"
171         "pass_2\n"
172         "#endif\n"
173         "pass_3\n";
174     const char *expected =
175         "pass_1\n"
176         "\n"
177         "\n"
178         "\n"
179         "\n"
180         "\n"
181         "\n"
182         "\n"
183         "pass_2\n"
184         "\n"
185         "pass_3\n";
186 
187     preprocess(str, expected);
188 }
189 
TEST_F(IfTest,If_0_Nested)190 TEST_F(IfTest, If_0_Nested)
191 {
192     const char *str =
193         "pass_1\n"
194         "#if 0\n"
195         "fail_1\n"
196         "#if 1\n"
197         "fail_2\n"
198         "#else\n"
199         "fail_3\n"
200         "#endif\n"
201         "#else\n"
202         "pass_2\n"
203         "#endif\n"
204         "pass_3\n";
205     const char *expected =
206         "pass_1\n"
207         "\n"
208         "\n"
209         "\n"
210         "\n"
211         "\n"
212         "\n"
213         "\n"
214         "\n"
215         "pass_2\n"
216         "\n"
217         "pass_3\n";
218 
219     preprocess(str, expected);
220 }
221 
TEST_F(IfTest,If_1_Nested)222 TEST_F(IfTest, If_1_Nested)
223 {
224     const char *str =
225         "pass_1\n"
226         "#if 1\n"
227         "pass_2\n"
228         "#if 1\n"
229         "pass_3\n"
230         "#else\n"
231         "fail_1\n"
232         "#endif\n"
233         "#else\n"
234         "fail_2\n"
235         "#endif\n"
236         "pass_4\n";
237     const char *expected =
238         "pass_1\n"
239         "\n"
240         "pass_2\n"
241         "\n"
242         "pass_3\n"
243         "\n"
244         "\n"
245         "\n"
246         "\n"
247         "\n"
248         "\n"
249         "pass_4\n";
250 
251     preprocess(str, expected);
252 }
253 
TEST_F(IfTest,OperatorPrecedence)254 TEST_F(IfTest, OperatorPrecedence)
255 {
256     const char *str =
257         "#if 1 + 2 * 3 + - (26 % 17 - + 4 / 2)\n"
258         "fail_1\n"
259         "#else\n"
260         "pass_1\n"
261         "#endif\n";
262     const char *expected =
263         "\n"
264         "\n"
265         "\n"
266         "pass_1\n"
267         "\n";
268 
269     preprocess(str, expected);
270 }
271 
TEST_F(IfTest,OperatorDefined)272 TEST_F(IfTest, OperatorDefined)
273 {
274     const char *str =
275         "#if defined foo\n"
276         "fail_1\n"
277         "#else\n"
278         "pass_1\n"
279         "#endif\n"
280         "#define foo\n"
281         "#if defined(foo)\n"
282         "pass_2\n"
283         "#else\n"
284         "fail_2\n"
285         "#endif\n"
286         "#undef foo\n"
287         "#if defined ( foo ) \n"
288         "fail_3\n"
289         "#else\n"
290         "pass_3\n"
291         "#endif\n";
292     const char *expected =
293         "\n"
294         "\n"
295         "\n"
296         "pass_1\n"
297         "\n"
298         "\n"
299         "\n"
300         "pass_2\n"
301         "\n"
302         "\n"
303         "\n"
304         "\n"
305         "\n"
306         "\n"
307         "\n"
308         "pass_3\n"
309         "\n";
310 
311     preprocess(str, expected);
312 }
313 
TEST_F(IfTest,OperatorEQ)314 TEST_F(IfTest, OperatorEQ)
315 {
316     const char *str =
317         "#if 4 - 1 == 2 + 1\n"
318         "pass\n"
319         "#else\n"
320         "fail\n"
321         "#endif\n";
322     const char *expected =
323         "\n"
324         "pass\n"
325         "\n"
326         "\n"
327         "\n";
328 
329     preprocess(str, expected);
330 }
331 
TEST_F(IfTest,OperatorNE)332 TEST_F(IfTest, OperatorNE)
333 {
334     const char *str =
335         "#if 1 != 2\n"
336         "pass\n"
337         "#else\n"
338         "fail\n"
339         "#endif\n";
340     const char *expected =
341         "\n"
342         "pass\n"
343         "\n"
344         "\n"
345         "\n";
346 
347     preprocess(str, expected);
348 }
349 
TEST_F(IfTest,OperatorLess)350 TEST_F(IfTest, OperatorLess)
351 {
352     const char *str =
353         "#if 1 < 2\n"
354         "pass\n"
355         "#else\n"
356         "fail\n"
357         "#endif\n";
358     const char *expected =
359         "\n"
360         "pass\n"
361         "\n"
362         "\n"
363         "\n";
364 
365     preprocess(str, expected);
366 }
367 
TEST_F(IfTest,OperatorGreater)368 TEST_F(IfTest, OperatorGreater)
369 {
370     const char *str =
371         "#if 2 > 1\n"
372         "pass\n"
373         "#else\n"
374         "fail\n"
375         "#endif\n";
376     const char *expected =
377         "\n"
378         "pass\n"
379         "\n"
380         "\n"
381         "\n";
382 
383     preprocess(str, expected);
384 }
385 
TEST_F(IfTest,OperatorLE)386 TEST_F(IfTest, OperatorLE)
387 {
388     const char *str =
389         "#if 1 <= 2\n"
390         "pass_1\n"
391         "#else\n"
392         "fail_1\n"
393         "#endif\n"
394         "#if 2 <= 2\n"
395         "pass_2\n"
396         "#else\n"
397         "fail_2\n"
398         "#endif\n";
399     const char *expected =
400         "\n"
401         "pass_1\n"
402         "\n"
403         "\n"
404         "\n"
405         "\n"
406         "pass_2\n"
407         "\n"
408         "\n"
409         "\n";
410 
411     preprocess(str, expected);
412 }
413 
TEST_F(IfTest,OperatorGE)414 TEST_F(IfTest, OperatorGE)
415 {
416     const char *str =
417         "#if 2 >= 1\n"
418         "pass_1\n"
419         "#else\n"
420         "fail_1\n"
421         "#endif\n"
422         "#if 2 >= 2\n"
423         "pass_2\n"
424         "#else\n"
425         "fail_2\n"
426         "#endif\n";
427     const char *expected =
428         "\n"
429         "pass_1\n"
430         "\n"
431         "\n"
432         "\n"
433         "\n"
434         "pass_2\n"
435         "\n"
436         "\n"
437         "\n";
438 
439     preprocess(str, expected);
440 }
441 
TEST_F(IfTest,OperatorBitwiseOR)442 TEST_F(IfTest, OperatorBitwiseOR)
443 {
444     const char *str =
445         "#if (0xaaaaaaaa | 0x55555555) == 0xffffffff\n"
446         "pass\n"
447         "#else\n"
448         "fail\n"
449         "#endif\n";
450     const char *expected =
451         "\n"
452         "pass\n"
453         "\n"
454         "\n"
455         "\n";
456 
457     preprocess(str, expected);
458 }
459 
TEST_F(IfTest,OperatorBitwiseAND)460 TEST_F(IfTest, OperatorBitwiseAND)
461 {
462     const char *str =
463         "#if (0xaaaaaaa & 0x5555555) == 0\n"
464         "pass\n"
465         "#else\n"
466         "fail\n"
467         "#endif\n";
468     const char *expected =
469         "\n"
470         "pass\n"
471         "\n"
472         "\n"
473         "\n";
474 
475     preprocess(str, expected);
476 }
477 
TEST_F(IfTest,OperatorBitwiseXOR)478 TEST_F(IfTest, OperatorBitwiseXOR)
479 {
480     const char *str =
481         "#if (0xaaaaaaa ^ 0x5555555) == 0xfffffff\n"
482         "pass\n"
483         "#else\n"
484         "fail\n"
485         "#endif\n";
486     const char *expected =
487         "\n"
488         "pass\n"
489         "\n"
490         "\n"
491         "\n";
492 
493     preprocess(str, expected);
494 }
495 
TEST_F(IfTest,OperatorBitwiseComplement)496 TEST_F(IfTest, OperatorBitwiseComplement)
497 {
498     const char *str =
499         "#if (~ 0xdeadbeef) == -3735928560\n"
500         "pass\n"
501         "#else\n"
502         "fail\n"
503         "#endif\n";
504     const char *expected =
505         "\n"
506         "pass\n"
507         "\n"
508         "\n"
509         "\n";
510 
511     preprocess(str, expected);
512 }
513 
TEST_F(IfTest,OperatorLeft)514 TEST_F(IfTest, OperatorLeft)
515 {
516     const char *str =
517         "#if (1 << 12) == 4096\n"
518         "pass\n"
519         "#else\n"
520         "fail\n"
521         "#endif\n";
522     const char *expected =
523         "\n"
524         "pass\n"
525         "\n"
526         "\n"
527         "\n";
528 
529     preprocess(str, expected);
530 }
531 
TEST_F(IfTest,OperatorRight)532 TEST_F(IfTest, OperatorRight)
533 {
534     const char *str =
535         "#if (31762 >> 8) == 124\n"
536         "pass\n"
537         "#else\n"
538         "fail\n"
539         "#endif\n";
540     const char *expected =
541         "\n"
542         "pass\n"
543         "\n"
544         "\n"
545         "\n";
546 
547     preprocess(str, expected);
548 }
549 
TEST_F(IfTest,ExpressionWithMacros)550 TEST_F(IfTest, ExpressionWithMacros)
551 {
552     const char *str =
553         "#define one 1\n"
554         "#define two 2\n"
555         "#define three 3\n"
556         "#if one + two == three\n"
557         "pass\n"
558         "#else\n"
559         "fail\n"
560         "#endif\n";
561     const char *expected =
562         "\n"
563         "\n"
564         "\n"
565         "\n"
566         "pass\n"
567         "\n"
568         "\n"
569         "\n";
570 
571     preprocess(str, expected);
572 }
573 
TEST_F(IfTest,JunkInsideExcludedBlockIgnored)574 TEST_F(IfTest, JunkInsideExcludedBlockIgnored)
575 {
576     const char *str =
577         "#if 0\n"
578         "foo !@#$%^&* .1bar\n"
579         "#foo\n"
580         "#if bar\n"
581         "fail\n"
582         "#endif\n"
583         "#else\n"
584         "pass\n"
585         "#endif\n";
586     const char *expected =
587         "\n"
588         "\n"
589         "\n"
590         "\n"
591         "\n"
592         "\n"
593         "\n"
594         "pass\n"
595         "\n";
596 
597     preprocess(str, expected);
598 }
599 
TEST_F(IfTest,Ifdef)600 TEST_F(IfTest, Ifdef)
601 {
602     const char *str =
603         "#define foo\n"
604         "#ifdef foo\n"
605         "pass_1\n"
606         "#else\n"
607         "fail_1\n"
608         "#endif\n"
609         "#undef foo\n"
610         "#ifdef foo\n"
611         "fail_2\n"
612         "#else\n"
613         "pass_2\n"
614         "#endif\n";
615     const char *expected =
616         "\n"
617         "\n"
618         "pass_1\n"
619         "\n"
620         "\n"
621         "\n"
622         "\n"
623         "\n"
624         "\n"
625         "\n"
626         "pass_2\n"
627         "\n";
628 
629     preprocess(str, expected);
630 }
631 
TEST_F(IfTest,Ifndef)632 TEST_F(IfTest, Ifndef)
633 {
634     const char *str =
635         "#define foo\n"
636         "#ifndef foo\n"
637         "fail_1\n"
638         "#else\n"
639         "pass_1\n"
640         "#endif\n"
641         "#undef foo\n"
642         "#ifndef foo\n"
643         "pass_2\n"
644         "#else\n"
645         "fail_2\n"
646         "#endif\n";
647     const char *expected =
648         "\n"
649         "\n"
650         "\n"
651         "\n"
652         "pass_1\n"
653         "\n"
654         "\n"
655         "\n"
656         "pass_2\n"
657         "\n"
658         "\n"
659         "\n";
660 
661     preprocess(str, expected);
662 }
663 
TEST_F(IfTest,MissingExpression)664 TEST_F(IfTest, MissingExpression)
665 {
666     const char *str =
667         "#if\n"
668         "#endif\n";
669 
670     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_INVALID_EXPRESSION,
671                                     pp::SourceLocation(0, 1), "syntax error"));
672 
673     preprocess(str);
674 }
675 
TEST_F(IfTest,DivisionByZero)676 TEST_F(IfTest, DivisionByZero)
677 {
678     const char *str =
679         "#if 1 / (3 - (1 + 2))\n"
680         "#endif\n";
681 
682     EXPECT_CALL(mDiagnostics,
683                 print(pp::Diagnostics::PP_DIVISION_BY_ZERO, pp::SourceLocation(0, 1), "1 / 0"));
684 
685     preprocess(str);
686 }
687 
TEST_F(IfTest,ModuloByZero)688 TEST_F(IfTest, ModuloByZero)
689 {
690     const char *str =
691         "#if 1 % (3 - (1 + 2))\n"
692         "#endif\n";
693 
694     EXPECT_CALL(mDiagnostics,
695                 print(pp::Diagnostics::PP_DIVISION_BY_ZERO, pp::SourceLocation(0, 1), "1 % 0"));
696 
697     preprocess(str);
698 }
699 
TEST_F(IfTest,DecIntegerOverflow)700 TEST_F(IfTest, DecIntegerOverflow)
701 {
702     const char *str =
703         "#if 4294967296\n"
704         "#endif\n";
705 
706     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_INTEGER_OVERFLOW, pp::SourceLocation(0, 1),
707                                     "4294967296"));
708 
709     preprocess(str);
710 }
711 
TEST_F(IfTest,OctIntegerOverflow)712 TEST_F(IfTest, OctIntegerOverflow)
713 {
714     const char *str =
715         "#if 077777777777\n"
716         "#endif\n";
717 
718     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_INTEGER_OVERFLOW, pp::SourceLocation(0, 1),
719                                     "077777777777"));
720 
721     preprocess(str);
722 }
723 
TEST_F(IfTest,HexIntegerOverflow)724 TEST_F(IfTest, HexIntegerOverflow)
725 {
726     const char *str =
727         "#if 0xfffffffff\n"
728         "#endif\n";
729 
730     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_INTEGER_OVERFLOW, pp::SourceLocation(0, 1),
731                                     "0xfffffffff"));
732 
733     preprocess(str);
734 }
735 
TEST_F(IfTest,UndefinedMacro)736 TEST_F(IfTest, UndefinedMacro)
737 {
738     const char *str =
739         "#if UNDEFINED\n"
740         "#endif\n";
741 
742     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
743                                     pp::SourceLocation(0, 1), "UNDEFINED"));
744 
745     preprocess(str);
746 }
747 
TEST_F(IfTest,InvalidExpressionIgnoredForExcludedElif)748 TEST_F(IfTest, InvalidExpressionIgnoredForExcludedElif)
749 {
750     const char *str =
751         "#if 1\n"
752         "pass\n"
753         "#elif UNDEFINED\n"
754         "fail\n"
755         "#endif\n";
756     const char *expected =
757         "\n"
758         "pass\n"
759         "\n"
760         "\n"
761         "\n";
762 
763     // No error or warning.
764     using testing::_;
765     EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
766 
767     preprocess(str, expected);
768 }
769 
TEST_F(IfTest,ElseWithoutIf)770 TEST_F(IfTest, ElseWithoutIf)
771 {
772     const char *str = "#else\n";
773 
774     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF,
775                                     pp::SourceLocation(0, 1), "else"));
776 
777     preprocess(str);
778 }
779 
TEST_F(IfTest,ElifWithoutIf)780 TEST_F(IfTest, ElifWithoutIf)
781 {
782     const char *str = "#elif 1\n";
783 
784     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF,
785                                     pp::SourceLocation(0, 1), "elif"));
786 
787     preprocess(str);
788 }
789 
TEST_F(IfTest,EndifWithoutIf)790 TEST_F(IfTest, EndifWithoutIf)
791 {
792     const char *str = "#endif\n";
793 
794     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF,
795                                     pp::SourceLocation(0, 1), "endif"));
796 
797     preprocess(str);
798 }
799 
TEST_F(IfTest,ElseAfterElse)800 TEST_F(IfTest, ElseAfterElse)
801 {
802     const char *str =
803         "#if 1\n"
804         "#else\n"
805         "#else\n"
806         "#endif\n";
807 
808     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_ELSE_AFTER_ELSE,
809                                     pp::SourceLocation(0, 3), "else"));
810 
811     preprocess(str);
812 }
813 
TEST_F(IfTest,ElifAfterElse)814 TEST_F(IfTest, ElifAfterElse)
815 {
816     const char *str =
817         "#if 1\n"
818         "#else\n"
819         "#elif 0\n"
820         "#endif\n";
821 
822     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_ELIF_AFTER_ELSE,
823                                     pp::SourceLocation(0, 3), "elif"));
824 
825     preprocess(str);
826 }
827 
TEST_F(IfTest,UnterminatedIf)828 TEST_F(IfTest, UnterminatedIf)
829 {
830     const char *str = "#if 1\n";
831 
832     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_UNTERMINATED,
833                                     pp::SourceLocation(0, 1), "if"));
834 
835     preprocess(str);
836 }
837 
TEST_F(IfTest,UnterminatedIfdef)838 TEST_F(IfTest, UnterminatedIfdef)
839 {
840     const char *str = "#ifdef foo\n";
841 
842     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_UNTERMINATED,
843                                     pp::SourceLocation(0, 1), "ifdef"));
844 
845     preprocess(str);
846 }
847 
848 // The preprocessor only allows one expression to follow an #if directive.
849 // Supplying two integer expressions should be an error.
TEST_F(IfTest,ExtraIntExpression)850 TEST_F(IfTest, ExtraIntExpression)
851 {
852     const char *str =
853         "#if 1 1\n"
854         "#endif\n";
855 
856     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
857                                     pp::SourceLocation(0, 1), "1"));
858 
859     preprocess(str);
860 }
861 
862 // The preprocessor only allows one expression to follow an #if directive.
863 // Supplying two expressions where one uses a preprocessor define should be an error.
TEST_F(IfTest,ExtraIdentifierExpression)864 TEST_F(IfTest, ExtraIdentifierExpression)
865 {
866     const char *str =
867         "#define one 1\n"
868         "#if 1 one\n"
869         "#endif\n";
870 
871     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
872                                     pp::SourceLocation(0, 2), "1"));
873 
874     preprocess(str);
875 }
876 
877 // Divide by zero that's not evaluated because of short-circuiting should not cause an error.
TEST_F(IfTest,ShortCircuitedDivideByZero)878 TEST_F(IfTest, ShortCircuitedDivideByZero)
879 {
880     const char *str =
881         "#if 1 || (2 / 0)\n"
882         "pass\n"
883         "#endif\n";
884     const char *expected =
885         "\n"
886         "pass\n"
887         "\n";
888 
889     preprocess(str, expected);
890 }
891 
892 // Undefined identifier that's not evaluated because of short-circuiting should not cause an error.
TEST_F(IfTest,ShortCircuitedUndefined)893 TEST_F(IfTest, ShortCircuitedUndefined)
894 {
895     const char *str =
896         "#if 1 || UNDEFINED\n"
897         "pass\n"
898         "#endif\n";
899     const char *expected =
900         "\n"
901         "pass\n"
902         "\n";
903 
904     preprocess(str, expected);
905 }
906 
907 // Defined operator produced by macro expansion has undefined behavior according to C++ spec,
908 // which the GLSL spec references (see C++14 draft spec section 16.1.4), but this behavior is
909 // needed for passing dEQP tests, which enforce stricter compatibility between implementations.
TEST_F(IfTest,DefinedOperatorValidAfterMacroExpansion)910 TEST_F(IfTest, DefinedOperatorValidAfterMacroExpansion)
911 {
912     const char *str =
913         "#define foo defined\n"
914         "#if !foo bar\n"
915         "pass\n"
916         "#endif\n";
917 
918     preprocess(str, "\n\npass\n\n");
919 }
920 
921 // Validate the defined operator is evaluated when the macro is called, not when defined.
TEST_F(IfTest,DefinedOperatorValidWhenUsed)922 TEST_F(IfTest, DefinedOperatorValidWhenUsed)
923 {
924     constexpr char str[] = R"(#define BBB 1
925 #define AAA defined(BBB)
926 #undef BBB
927 
928 #if !AAA
929 pass
930 #endif
931 )";
932 
933     preprocess(str, "\n\n\n\n\npass\n\n");
934 }
935 
936 // Validate the defined operator is evaluated when the macro is called, not when defined.
TEST_F(IfTest,DefinedOperatorAfterMacro)937 TEST_F(IfTest, DefinedOperatorAfterMacro)
938 {
939     constexpr char str[] = R"(#define AAA defined(BBB)
940 #define BBB 1
941 
942 #if AAA
943 pass
944 #endif
945 )";
946 
947     preprocess(str, "\n\n\n\npass\n\n");
948 }
949 
950 // Test generating "defined" by concatenation when a macro is called. This is not allowed.
TEST_F(IfTest,DefinedInMacroConcatenationNotAllowed)951 TEST_F(IfTest, DefinedInMacroConcatenationNotAllowed)
952 {
953     constexpr char str[] = R"(#define BBB 1
954 #define AAA(defi, ned) defi ## ned(BBB)
955 
956 #if !AAA(defi, ned)
957 pass
958 #endif
959 )";
960 
961     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
962                                     pp::SourceLocation(0, 4), "defi"));
963     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
964                                     pp::SourceLocation(0, 4), "#"));
965 
966     preprocess(str);
967 }
968 
969 // Test using defined in a macro parameter name. This is not allowed.
TEST_F(IfTest,DefinedAsParameterNameNotAllowed)970 TEST_F(IfTest, DefinedAsParameterNameNotAllowed)
971 {
972     constexpr char str[] = R"(#define BBB 1
973 #define AAA(defined) defined(BBB)
974 
975 #if AAA(defined)
976 pass
977 #endif
978 )";
979 
980     EXPECT_CALL(mDiagnostics,
981                 print(pp::Diagnostics::PP_UNEXPECTED_TOKEN, pp::SourceLocation(0, 0), ""));
982 
983     preprocess(str);
984 }
985 
986 // This behavour is disabled in WebGL.
TEST_F(IfTest,DefinedOperatorInvalidAfterMacroExpansionInWebGL)987 TEST_F(IfTest, DefinedOperatorInvalidAfterMacroExpansionInWebGL)
988 {
989     const char *str =
990         "#define foo defined\n"
991         "#if !foo bar\n"
992         "pass\n"
993         "#endif\n";
994 
995     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
996                                     pp::SourceLocation(0, 2), "defined"));
997     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
998                                     pp::SourceLocation(0, 2), "bar"));
999 
1000     preprocess(str, pp::PreprocessorSettings(SH_WEBGL_SPEC));
1001 }
1002 
1003 // Defined operator produced by macro expansion has undefined behavior according to C++ spec,
1004 // which the GLSL spec references (see C++14 draft spec section 16.1.4). Some edge case
1005 // behaviours with defined are not portable between implementations and thus are not required
1006 // to pass dEQP Tests.
TEST_F(IfTest,UnterminatedDefinedInMacro)1007 TEST_F(IfTest, UnterminatedDefinedInMacro)
1008 {
1009     const char *str =
1010         "#define foo defined(\n"
1011         "#if foo\n"
1012         "#endif\n";
1013 
1014     EXPECT_CALL(mDiagnostics,
1015                 print(pp::Diagnostics::PP_UNEXPECTED_TOKEN, pp::SourceLocation(0, 2), "\n"));
1016     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_INVALID_EXPRESSION,
1017                                     pp::SourceLocation(0, 2), "syntax error"));
1018 
1019     preprocess(str);
1020 }
1021 
1022 // Defined operator produced by macro expansion has undefined behavior according to C++ spec,
1023 // which the GLSL spec references (see C++14 draft spec section 16.1.4). Some edge case
1024 // behaviours with defined are not portable between implementations and thus are not required
1025 // to pass dEQP Tests.
TEST_F(IfTest,UnterminatedDefinedInMacro2)1026 TEST_F(IfTest, UnterminatedDefinedInMacro2)
1027 {
1028     const char *str =
1029         "#define foo defined(bar\n"
1030         "#if foo\n"
1031         "#endif\n";
1032 
1033     EXPECT_CALL(mDiagnostics,
1034                 print(pp::Diagnostics::PP_UNEXPECTED_TOKEN, pp::SourceLocation(0, 2), "\n"));
1035     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_INVALID_EXPRESSION,
1036                                     pp::SourceLocation(0, 2), "syntax error"));
1037 
1038     preprocess(str);
1039 }
1040 
1041 // Undefined shift: negative shift offset.
TEST_F(IfTest,BitShiftLeftOperatorNegativeOffset)1042 TEST_F(IfTest, BitShiftLeftOperatorNegativeOffset)
1043 {
1044     const char *str =
1045         "#if 2 << -1 == 1\n"
1046         "foo\n"
1047         "#endif\n";
1048 
1049     EXPECT_CALL(mDiagnostics,
1050                 print(pp::Diagnostics::PP_UNDEFINED_SHIFT, pp::SourceLocation(0, 1), "2 << -1"));
1051 
1052     preprocess(str);
1053 }
1054 
1055 // Undefined shift: shift offset is out of range.
TEST_F(IfTest,BitShiftLeftOperatorOffset32)1056 TEST_F(IfTest, BitShiftLeftOperatorOffset32)
1057 {
1058     const char *str =
1059         "#if 2 << 32 == 1\n"
1060         "foo\n"
1061         "#endif\n";
1062 
1063     EXPECT_CALL(mDiagnostics,
1064                 print(pp::Diagnostics::PP_UNDEFINED_SHIFT, pp::SourceLocation(0, 1), "2 << 32"));
1065 
1066     preprocess(str);
1067 }
1068 
1069 // Left hand side of shift is negative.
TEST_F(IfTest,BitShiftLeftOperatorNegativeLHS)1070 TEST_F(IfTest, BitShiftLeftOperatorNegativeLHS)
1071 {
1072     const char *str =
1073         "#if (-2) << 1 == -4\n"
1074         "pass\n"
1075         "#endif\n";
1076     const char *expected =
1077         "\n"
1078         "pass\n"
1079         "\n";
1080 
1081     preprocess(str, expected);
1082 }
1083 
1084 // Left shift overflows. Note that the intended result is not explicitly specified, but we assume it
1085 // to do the same operation on the 2's complement bit representation as unsigned shift in C++.
TEST_F(IfTest,BitShiftLeftOverflow)1086 TEST_F(IfTest, BitShiftLeftOverflow)
1087 {
1088     const char *str =
1089         "#if (0x10000 + 0x1) << 28 == 0x10000000\n"
1090         "pass\n"
1091         "#endif\n";
1092     const char *expected =
1093         "\n"
1094         "pass\n"
1095         "\n";
1096 
1097     preprocess(str, expected);
1098 }
1099 
1100 // Left shift of a negative number overflows. Note that the intended result is not explicitly
1101 // specified, but we assume it to do the same operation on the 2's complement bit representation as
1102 // unsigned shift in C++.
TEST_F(IfTest,BitShiftLeftNegativeOverflow)1103 TEST_F(IfTest, BitShiftLeftNegativeOverflow)
1104 {
1105     // The bit representation of -5 is 11111111 11111111 11111111 11111011.
1106     // Shifting by 30 leaves:          11000000 00000000 00000000 00000000.
1107     const char *str =
1108         "#if (-5) << 30 == -1073741824\n"
1109         "pass\n"
1110         "#endif\n";
1111     const char *expected =
1112         "\n"
1113         "pass\n"
1114         "\n";
1115 
1116     preprocess(str, expected);
1117 }
1118 
1119 // Undefined shift: shift offset is out of range.
TEST_F(IfTest,BitShiftRightOperatorNegativeOffset)1120 TEST_F(IfTest, BitShiftRightOperatorNegativeOffset)
1121 {
1122     const char *str =
1123         "#if 2 >> -1 == 4\n"
1124         "foo\n"
1125         "#endif\n";
1126 
1127     EXPECT_CALL(mDiagnostics,
1128                 print(pp::Diagnostics::PP_UNDEFINED_SHIFT, pp::SourceLocation(0, 1), "2 >> -1"));
1129 
1130     preprocess(str);
1131 }
1132 
1133 // Undefined shift: shift offset is out of range.
TEST_F(IfTest,BitShiftRightOperatorOffset32)1134 TEST_F(IfTest, BitShiftRightOperatorOffset32)
1135 {
1136     const char *str =
1137         "#if 2 >> 32 == 0\n"
1138         "foo\n"
1139         "#endif\n";
1140 
1141     EXPECT_CALL(mDiagnostics,
1142                 print(pp::Diagnostics::PP_UNDEFINED_SHIFT, pp::SourceLocation(0, 1), "2 >> 32"));
1143 
1144     preprocess(str);
1145 }
1146 
1147 // Left hand side of shift is negative.
TEST_F(IfTest,BitShiftRightOperatorNegativeLHS)1148 TEST_F(IfTest, BitShiftRightOperatorNegativeLHS)
1149 {
1150     const char *str =
1151         "#if (-2) >> 1 == 0x7fffffff\n"
1152         "pass\n"
1153         "#endif\n";
1154     const char *expected =
1155         "\n"
1156         "pass\n"
1157         "\n";
1158 
1159     preprocess(str, expected);
1160 }
1161 
1162 }  // namespace angle
1163