xref: /aosp_15_r20/external/clang/test/Preprocessor/ucn-pp-identifier.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 %s -fsyntax-only -std=c99 -pedantic -verify -Wundef
2*67e74705SXin Li // RUN: %clang_cc1 %s -fsyntax-only -x c++ -pedantic -verify -Wundef
3*67e74705SXin Li // RUN: not %clang_cc1 %s -fsyntax-only -std=c99 -pedantic -Wundef 2>&1 | FileCheck -strict-whitespace %s
4*67e74705SXin Li 
5*67e74705SXin Li #define \u00FC
6*67e74705SXin Li #define a\u00FD() 0
7*67e74705SXin Li #ifndef \u00FC
8*67e74705SXin Li #error "This should never happen"
9*67e74705SXin Li #endif
10*67e74705SXin Li 
11*67e74705SXin Li #if a\u00FD()
12*67e74705SXin Li #error "This should never happen"
13*67e74705SXin Li #endif
14*67e74705SXin Li 
15*67e74705SXin Li #if a\U000000FD()
16*67e74705SXin Li #error "This should never happen"
17*67e74705SXin Li #endif
18*67e74705SXin Li 
19*67e74705SXin Li #if \uarecool // expected-warning{{incomplete universal character name; treating as '\' followed by identifier}} expected-error {{invalid token at start of a preprocessor expression}}
20*67e74705SXin Li #endif
21*67e74705SXin Li #if \uwerecool // expected-warning{{\u used with no following hex digits; treating as '\' followed by identifier}} expected-error {{invalid token at start of a preprocessor expression}}
22*67e74705SXin Li #endif
23*67e74705SXin Li #if \U0001000  // expected-warning{{incomplete universal character name; treating as '\' followed by identifier}} expected-error {{invalid token at start of a preprocessor expression}}
24*67e74705SXin Li #endif
25*67e74705SXin Li 
26*67e74705SXin Li // Make sure we reject disallowed UCNs
27*67e74705SXin Li #define \ufffe // expected-error {{macro name must be an identifier}}
28*67e74705SXin Li #define \U10000000  // expected-error {{macro name must be an identifier}}
29*67e74705SXin Li #define \u0061  // expected-error {{character 'a' cannot be specified by a universal character name}} expected-error {{macro name must be an identifier}}
30*67e74705SXin Li 
31*67e74705SXin Li // FIXME: Not clear what our behavior should be here; \u0024 is "$".
32*67e74705SXin Li #define a\u0024  // expected-warning {{whitespace}}
33*67e74705SXin Li 
34*67e74705SXin Li #if \u0110 // expected-warning {{is not defined, evaluates to 0}}
35*67e74705SXin Li #endif
36*67e74705SXin Li 
37*67e74705SXin Li 
38*67e74705SXin Li #define \u0110 1 / 0
39*67e74705SXin Li #if \u0110 // expected-error {{division by zero in preprocessor expression}}
40*67e74705SXin Li #endif
41*67e74705SXin Li 
42*67e74705SXin Li #define STRINGIZE(X) # X
43*67e74705SXin Li 
44*67e74705SXin Li extern int check_size[sizeof(STRINGIZE(\u0112)) == 3 ? 1 : -1];
45*67e74705SXin Li 
46*67e74705SXin Li // Check that we still diagnose disallowed UCNs in #if 0 blocks.
47*67e74705SXin Li // C99 5.1.1.2p1 and C++11 [lex.phases]p1 dictate that preprocessor tokens are
48*67e74705SXin Li // formed before directives are parsed.
49*67e74705SXin Li // expected-error@+4 {{character 'a' cannot be specified by a universal character name}}
50*67e74705SXin Li #if 0
51*67e74705SXin Li #define \ufffe // okay
52*67e74705SXin Li #define \U10000000 // okay
53*67e74705SXin Li #define \u0061 // error, but -verify only looks at comments outside #if 0
54*67e74705SXin Li #endif
55*67e74705SXin Li 
56*67e74705SXin Li 
57*67e74705SXin Li // A UCN formed by token pasting is undefined in both C99 and C++.
58*67e74705SXin Li // Right now we don't do anything special, which causes us to coincidentally
59*67e74705SXin Li // accept the first case below but reject the second two.
60*67e74705SXin Li #define PASTE(A, B) A ## B
61*67e74705SXin Li extern int PASTE(\, u00FD);
62*67e74705SXin Li extern int PASTE(\u, 00FD); // expected-warning{{\u used with no following hex digits}}
63*67e74705SXin Li extern int PASTE(\u0, 0FD); // expected-warning{{incomplete universal character name}}
64*67e74705SXin Li #ifdef __cplusplus
65*67e74705SXin Li // expected-error@-3 {{expected unqualified-id}}
66*67e74705SXin Li // expected-error@-3 {{expected unqualified-id}}
67*67e74705SXin Li #else
68*67e74705SXin Li // expected-error@-6 {{expected identifier}}
69*67e74705SXin Li // expected-error@-6 {{expected identifier}}
70*67e74705SXin Li #endif
71*67e74705SXin Li 
72*67e74705SXin Li 
73*67e74705SXin Li // A UCN produced by line splicing is valid in C99 but undefined in C++.
74*67e74705SXin Li // Since undefined behavior can do anything including working as intended,
75*67e74705SXin Li // we just accept it in C++ as well.;
76*67e74705SXin Li #define newline_1_\u00F\
77*67e74705SXin Li C 1
78*67e74705SXin Li #define newline_2_\u00\
79*67e74705SXin Li F\
80*67e74705SXin Li C 1
81*67e74705SXin Li #define newline_3_\u\
82*67e74705SXin Li 00\
83*67e74705SXin Li FC 1
84*67e74705SXin Li #define newline_4_\\
85*67e74705SXin Li u00FC 1
86*67e74705SXin Li #define newline_5_\\
87*67e74705SXin Li u\
88*67e74705SXin Li \
89*67e74705SXin Li 0\
90*67e74705SXin Li 0\
91*67e74705SXin Li F\
92*67e74705SXin Li C 1
93*67e74705SXin Li 
94*67e74705SXin Li #if (newline_1_\u00FC && newline_2_\u00FC && newline_3_\u00FC && \
95*67e74705SXin Li      newline_4_\u00FC && newline_5_\u00FC)
96*67e74705SXin Li #else
97*67e74705SXin Li #error "Line splicing failed to produce UCNs"
98*67e74705SXin Li #endif
99*67e74705SXin Li 
100*67e74705SXin Li 
101*67e74705SXin Li #define capital_u_\U00FC
102*67e74705SXin Li // expected-warning@-1 {{incomplete universal character name}} expected-note@-1 {{did you mean to use '\u'?}} expected-warning@-1 {{whitespace}}
103*67e74705SXin Li // CHECK: note: did you mean to use '\u'?
104*67e74705SXin Li // CHECK-NEXT:   #define capital_u_\U00FC
105*67e74705SXin Li // CHECK-NEXT: {{^                   \^}}
106*67e74705SXin Li // CHECK-NEXT: {{^                   u}}
107