File: c2x-typeof.c

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (141 lines) | stat: -rw-r--r-- 5,405 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// RUN: %clang_cc1 -verify -std=c2x %s

// Demonstrate that we get the correct type information. Do this by leaning
// heavily on redeclarations needing to use the same type for both decls.
extern int i;
extern typeof(i) i;
extern typeof_unqual(i) i;

extern const int j;
extern typeof(j) j;

extern const int n;         // expected-note 2 {{previous declaration is here}}
extern typeof(i) n;         // expected-error {{redeclaration of 'n' with a different type: 'typeof (i)' (aka 'int') vs 'const int'}}
extern typeof_unqual(n) n;  // expected-error {{redeclaration of 'n' with a different type: 'typeof_unqual (n)' (aka 'int') vs 'const int'}}

// Ensure we get a redeclaration error here for the types not matching.
extern typeof(j) k;        // expected-note {{previous declaration is here}}
extern typeof_unqual(j) k; // expected-error {{redeclaration of 'k' with a different type: 'typeof_unqual (j)' (aka 'int') vs 'typeof (j)' (aka 'const int')}}

// Make sure the type-form of the operator also works.
extern typeof(int) l;
extern typeof_unqual(const int) l;

extern typeof(const int) m;        // expected-note {{previous declaration is here}}
extern typeof_unqual(const int) m; // expected-error {{redeclaration of 'm' with a different type: 'typeof_unqual(const int)' (aka 'int') vs 'typeof(const int)' (aka 'const int')}}

// Show that we can use an incomplete type which is then completed later.
extern typeof(struct T) *o;
struct T { int a; } t;
extern typeof(struct T) *o;
extern typeof(t) *o;
extern typeof(&t) o;
extern typeof_unqual(volatile struct T) *o;
extern typeof_unqual(t) *o;
extern typeof_unqual(&t) o;

// Show that we properly strip the _Atomic qualifier.
extern _Atomic int i2;
extern _Atomic(int) i2;
extern typeof(i2) i2;        // expected-note {{previous declaration is here}}
extern typeof_unqual(i2) i2; // expected-error {{redeclaration of 'i2' with a different type: 'typeof_unqual (i2)' (aka 'int') vs 'typeof (i2)' (aka '_Atomic(int)')}}

// We cannot take the type of a bit-field.
struct S {
  int bit : 4;
} s;

typeof(s.bit) nope1; // expected-error {{invalid application of 'typeof' to bit-field}}
typeof_unqual(s.bit) nope2; // expected-error {{invalid application of 'typeof_unqual' to bit-field}}

// Show that we properly resolve nested typeof specifiers.
extern typeof(typeof(0)) i3;
extern typeof(typeof(int)) i3;
extern typeof(typeof_unqual(0)) i3;
extern typeof(typeof_unqual(int)) i3;
extern typeof_unqual(typeof(0)) i3;
extern typeof_unqual(typeof(int)) i3;
extern typeof_unqual(typeof_unqual(0)) i3;
extern typeof_unqual(typeof_unqual(int)) i3;
extern typeof(typeof_unqual(j)) i3;
extern typeof(typeof_unqual(const int)) i3;
extern typeof_unqual(typeof(j)) i3;
extern typeof_unqual(typeof(const int)) i3;
extern typeof_unqual(typeof_unqual(j)) i3;
extern typeof_unqual(typeof_unqual(const int)) i3;

// Both of these result in a const int rather than an int.
extern typeof(typeof(j)) i4;
extern typeof(typeof(const int)) i4;

// Ensure that redundant qualifiers are allowed, same as with typedefs.
typedef const int CInt;
extern CInt i4;
extern const CInt i4;
extern const typeof(j) i4;
extern const typeof(const int) i4;
extern const typeof(CInt) i4;

// Qualifiers are not redundant here, but validating that the qualifiers are
// still honored.
extern const typeof_unqual(j) i4;
extern const typeof_unqual(const int) i4;
extern const typeof_unqual(CInt) i4;

// Show that type attributes are stripped from the unqualified version.
extern __attribute__((address_space(0))) int type_attr_test_2_obj;
extern int type_attr_test_2;
extern typeof_unqual(type_attr_test_2_obj) type_attr_test_2;            // expected-note {{previous declaration is here}}
extern __attribute__((address_space(0))) int type_attr_test_2;          // expected-error {{redeclaration of 'type_attr_test_2' with a different type: '__attribute__((address_space(0))) int' vs 'typeof_unqual (type_attr_test_2_obj)' (aka 'int')}}

// Ensure that an invalid type doesn't cause crashes.
void invalid_param_fn(__attribute__((address_space(1))) int i); // expected-error {{parameter may not be qualified with an address space}}
typeof(invalid_param_fn) invalid_param_1;
typeof_unqual(invalid_param_fn) invalid_param_2;

// Ensure restrict is stripped
extern int *restrict p1;
extern int *p2;
extern typeof(p1) p1;
extern typeof_unqual(p1) p2;

// Ensure array qualifications are removed
extern const int aci[2];
extern const int acii[2][2];
extern int ai[2];
extern int aii[2][2];
extern typeof(aci) aci;
extern typeof_unqual(aci) ai;
extern typeof(acii) acii;
extern typeof_unqual(acii) aii;

extern int *restrict arpi[2];
extern int *restrict arpii[2][2];
extern int *api[2];
extern int *apii[2][2];
extern typeof(arpi) arpi;
extern typeof_unqual(arpi) api;
extern typeof(arpii) arpii;
extern typeof_unqual(arpii) apii;

extern int _Atomic aAi[2];
extern int _Atomic aAii[2][2];
extern typeof(aAi) aAi;
extern typeof_unqual(aAi) aAi;
extern typeof(aAii) aAii;
extern typeof_unqual(aAii) aAii;

extern _Atomic(int) aAi[2];
extern _Atomic(int) aAii[2][2];
extern typeof(aAi) aAi;
extern typeof_unqual(aAi) aAi;
extern typeof(aAii) aAii;
extern typeof_unqual(aAii) aAii;

const char* const animals[] = { "aardvark", "bluejay", "catte" };
void GH92667(void) {
 const char* animals2_array1[3];
 typeof_unqual(animals) animals2_array;
 animals2_array1[0] = 0;
 animals2_array[0] = 0;
}