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