c23.c revision 1.12 1 1.12 rillig /* $NetBSD: c23.c,v 1.12 2024/05/09 20:56:41 rillig Exp $ */
2 1.1 rillig # 3 "c23.c"
3 1.1 rillig
4 1.1 rillig // Tests for the option -Ac23, which allows features from C23 and all earlier
5 1.1 rillig // ISO standards, but none of the GNU extensions.
6 1.1 rillig //
7 1.1 rillig // See also:
8 1.7 rillig // c11.c
9 1.3 rillig // msg_353.c for empty initializer braces
10 1.1 rillig
11 1.1 rillig /* lint1-flags: -Ac23 -w -X 351 */
12 1.1 rillig
13 1.9 rillig
14 1.9 rillig int
15 1.9 rillig bool_is_predefined_in_c23(void)
16 1.9 rillig {
17 1.9 rillig bool t = true;
18 1.9 rillig bool f = false;
19 1.9 rillig return (t == true ? 20 : 0) + (f == false ? 3 : 0);
20 1.9 rillig }
21 1.9 rillig
22 1.9 rillig int
23 1.9 rillig c99_bool_is_still_valid_in_c23(void)
24 1.9 rillig {
25 1.9 rillig _Bool t = 1;
26 1.9 rillig _Bool f = 0;
27 1.9 rillig return (t == 1 ? 20 : 0) + (f == 0 ? 3 : 0);
28 1.9 rillig }
29 1.9 rillig
30 1.9 rillig
31 1.11 rillig bool
32 1.11 rillig null_pointer_constant(const char *p, double dbl)
33 1.11 rillig {
34 1.11 rillig /* expect+1: error: operands of '!=' have incompatible types 'double' and 'pointer to void' [107] */
35 1.11 rillig if (dbl != nullptr)
36 1.11 rillig p++;
37 1.11 rillig if (dbl > 0.0)
38 1.11 rillig p++;
39 1.11 rillig if (*p == '\0')
40 1.11 rillig p = nullptr;
41 1.11 rillig return p == nullptr;
42 1.11 rillig }
43 1.11 rillig
44 1.11 rillig
45 1.12 rillig void *
46 1.12 rillig storage_class_in_compound_literal(void)
47 1.12 rillig {
48 1.12 rillig typedef struct node node;
49 1.12 rillig struct node {
50 1.12 rillig node *left;
51 1.12 rillig int value;
52 1.12 rillig node *right;
53 1.12 rillig };
54 1.12 rillig
55 1.12 rillig node *tree;
56 1.12 rillig tree = &(static node){
57 1.12 rillig &(static node){
58 1.12 rillig nullptr,
59 1.12 rillig 3,
60 1.12 rillig nullptr,
61 1.12 rillig },
62 1.12 rillig 5,
63 1.12 rillig nullptr,
64 1.12 rillig };
65 1.12 rillig return tree->left;
66 1.12 rillig }
67 1.12 rillig
68 1.1 rillig int
69 1.3 rillig empty_initializer_braces(void)
70 1.1 rillig {
71 1.1 rillig struct s {
72 1.1 rillig int member;
73 1.1 rillig } s;
74 1.1 rillig
75 1.2 rillig // Empty initializer braces were introduced in C23.
76 1.1 rillig s = (struct s){};
77 1.1 rillig s = (struct s){s.member};
78 1.1 rillig return s.member;
79 1.1 rillig }
80 1.2 rillig
81 1.7 rillig
82 1.7 rillig _Static_assert(1 > 0, "string");
83 1.7 rillig _Static_assert(1 > 0);
84 1.7 rillig
85 1.7 rillig
86 1.2 rillig // The keyword 'thread_local' was introduced in C23.
87 1.2 rillig thread_local int globally_visible;
88 1.2 rillig
89 1.3 rillig // Thread-local functions don't make sense; lint allows them, though.
90 1.2 rillig thread_local void
91 1.2 rillig thread_local_function(void)
92 1.2 rillig {
93 1.2 rillig }
94 1.2 rillig
95 1.2 rillig void
96 1.2 rillig function(void)
97 1.2 rillig {
98 1.2 rillig // Not sure whether it makes sense to have a function-scoped
99 1.2 rillig // thread-local variable. Don't warn for now, let the compilers handle
100 1.2 rillig // this case.
101 1.2 rillig thread_local int function_scoped_thread_local;
102 1.2 rillig }
103 1.4 rillig
104 1.6 rillig // 'thread_local' can be combined with 'extern' and 'static', but with no other
105 1.6 rillig // storage classes. The other storage classes cannot be combined.
106 1.4 rillig extern thread_local int extern_thread_local_1;
107 1.4 rillig thread_local extern int extern_thread_local_2;
108 1.8 rillig /* expect+1: warning: static variable 'static_thread_local_1' unused [226] */
109 1.6 rillig static thread_local int static_thread_local_1;
110 1.8 rillig /* expect+1: warning: static variable 'static_thread_local_2' unused [226] */
111 1.6 rillig thread_local static int static_thread_local_2;
112