Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/preprocessor_tests/if_test.cpp
1693 views
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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++.
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++.
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.
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.
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.
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
1164