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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
|
/* RUN: %clang_cc1 -std=c89 -verify=expected,c89only,pre-c23 -pedantic -Wno-c11-extensions %s
RUN: %clang_cc1 -std=c99 -verify=expected,pre-c23 -pedantic -Wno-c11-extensions %s
RUN: %clang_cc1 -std=c11 -verify=expected,pre-c23 -pedantic %s
RUN: %clang_cc1 -std=c17 -verify=expected,pre-c23 -pedantic %s
RUN: %clang_cc1 -std=c2x -verify=expected -pedantic %s
*/
/* The following are DRs which do not require tests to demonstrate
* conformance or nonconformance.
*
* WG14 DR401: yes
* "happens before" can not be cyclic
*
* WG14 DR402: yes
* Memory model coherence is not aligned with C++11
*
* WG14 DR404: yes
* Joke fragment remains in a footnote
*
* WG14 DR406: yes
* Visible sequences of side effects are redundant
*
* WG14 DR415: yes
* Missing divide by zero entry in Annex J
*
* WG14 DR417: yes
* Annex J not updated with necessary aligned_alloc entries
*
* WG14 DR419: yes
* Generic Functions
*
* WG14 DR420: yes
* Sytax error in specification of for-statement
*
* WG14 DR425: yes
* No specification for the access to variables with temporary lifetime
*
* WG14 DR434: yes
* Possible defect report: Missing constraint w.r.t. Atomic
*
* WG14 DR435: yes
* Possible defect report: Missing constraint w.r.t. Imaginary
*
* WG14 DR436: yes
* Request for interpretation of C11 6.8.5#6
* Note: This is not really testable because it requires -O1 or higher for LLVM
* to perform its reachability analysis and -Wunreachable-code only verifies
* diagnostic behavior, not runtime behavior. Also, both are a matter of QoI as
* to what they optimize/diagnose. But if someone thinks of a way to test this,
* we can add a test case for it then.
*
* WG14 DR448: yes
* What are the semantics of a # non-directive?
*
* WG14 DR454: yes
* ATOMIC_VAR_INIT (issues 3 and 4)
*
* WG14 DR455: yes
* ATOMIC_VAR_INIT issue 5
*
* WG14 DR459: yes
* atomic_load missing const qualifier
*
* WG14 DR475: yes
* Misleading Atomic library references to atomic types
*
* WG14 DR485: yes
* Problem with the specification of ATOMIC_VAR_INIT
*
* WG14 DR486: yes
* Inconsistent specification for arithmetic on atomic objects
*
* WG14 DR490: yes
* Unwritten Assumptions About if-then
*/
/* WG14 DR412: yes
* #elif
*
* Note: this is testing that #elif behaves the same as #else followed by #if.
*/
#if 1
#elif this is not a valid expression
#else
#if this is not a valid expression
#endif
#endif
/* WG14 DR413: yes
* Initialization
*/
void dr413(void) {
typedef struct {
int k;
int l;
int a[2];
} T;
typedef struct {
int i;
T t;
} S;
/* Ensure that explicit initialization (.t = { ... }) takes precedence over a
* later implicit partial initialization (.t.l = 41). The value should be 42,
* not 0.
*/
_Static_assert((S){ /* c89only-warning {{compound literals are a C99-specific feature}}
expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
*/
1,
.t = { /* c89only-warning {{designated initializers are a C99 feature}} */
.l = 43, /* c89only-warning {{designated initializers are a C99 feature}}
expected-note {{previous initialization is here}}
*/
.k = 42,
.a[1] = 19, /* expected-note {{previous initialization is here}} */
.a[0] = 18
},
.t.l = 41, /* expected-warning {{initializer overrides prior initialization of this subobject}} */
.t.a[1] = 17 /* expected-warning {{initializer overrides prior initialization of this subobject}} */
}.t.k == 42, "");
}
/* WG14 DR423: partial
* Defect Report relative to n1570: underspecification for qualified rvalues
*/
/* FIXME: this should pass because the qualifier on the return type should be
* dropped when forming the function type.
*/
const int dr423_const(void);
int dr423_nonconst(void);
_Static_assert(__builtin_types_compatible_p(__typeof__(dr423_const), __typeof__(dr423_nonconst)), "fail"); /* expected-error {{fail}} */
void dr423_func(void) {
const int i = 12;
__typeof__(i) v1 = 12; /* expected-note {{variable 'v1' declared const here}} */
__typeof__((const int)12) v2 = 12;
v1 = 100; /* expected-error {{cannot assign to variable 'v1' with const-qualified type 'typeof (i)' (aka 'const int')}} */
v2 = 100; /* Not an error; the qualifier was stripped. */
}
/* WG14 DR432: yes
* Possible defect report: Is 0.0 required to be a representable value?
*
* We're going to lean on the fpclassify builtin to tell us whether 0.0
* represents the value 0, and we'll test that adding and subtracting 0.0 does
* not change the value, and we'll hope that's enough to validate this DR.
*/
_Static_assert(__builtin_fpclassify(0, 1, 2, 3, 4, 0.0f) == 4, "");
_Static_assert((1.0 / 3.0) + 0.0 == (1.0 / 3.0) - 0.0, ""); /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}} */
/* WG14 DR444: partial
* Issues with alignment in C11, part 1
*/
void dr444(void) {
_Alignas(int) int i;
_Alignas(int) struct S {
_Alignas(int) int i;
} s;
/* FIXME: This should be accepted as per this DR. */
int j = (_Alignas(int) int){12}; /* expected-error {{expected expression}} */
_Alignas(int) struct T { /* expected-warning {{'_Alignas' attribute ignored}} */
int i;
};
struct U {
_Alignas(int) int bit : 1; /* expected-error {{'_Alignas' attribute cannot be applied to a bit-field}} */
};
_Alignas(int) typedef int foo; /* expected-error {{'_Alignas' attribute only applies to variables and fields}} */
_Alignas(int) register int bar; /* expected-error {{'_Alignas' attribute cannot be applied to a variable with 'register' storage class}} */
_Alignas(int) void func(void); /* expected-error {{'_Alignas' attribute only applies to variables and fields}} */
/* FIXME: it is correct for us to accept this per 6.7.3p5, but it seems like
* a situation we'd want to diagnose because the alignments are different and
* the user probably doesn't know which one "wins".
*/
_Alignas(int) _Alignas(double) int k;
}
/* WG14 DR447: yes
* Boolean from complex
*
* Ensure that the imaginary part contributes to the conversion to bool, not
* just the real part.
*/
_Static_assert((_Bool)0.0 + 3.0 * (__extension__ 1.0iF), ""); /* c89only-warning {{'_Bool' is a C99 extension}}
expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
*/
_Static_assert(!(_Bool)0.0 + 0.0 * (__extension__ 1.0iF), ""); /* c89only-warning {{'_Bool' is a C99 extension}}
expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
*/
/* WG14 DR463: yes
* Left-shifting into the sign bit
*
* This DR was NAD and leaves shifting a bit into the high bit of a signed
* integer type undefined behavior, unlike in C++. Note, the diagnostic is also
* issued in C++ for shifting into that bit despite being well-defined because
* the code is questionable and should be validated by the programmer.
*/
void dr463(void) {
(void)(1 << (__CHAR_BIT__ * sizeof(int))); /* expected-warning {{shift count >= width of type}} */
(void)(1 << ((__CHAR_BIT__ * sizeof(int)) - 1));
}
/* WG14 DR478: yes
* Valid uses of the main function
*/
int main(void) {
/* This DR clarifies that C explicitly allows you to call main() in a hosted
* environment; it is not special as it is in C++, so recursive calls are
* fine as well as nonrecursive direct calls.
*/
main(); /* ok */
}
void dr478(void) {
int (*fp)(void) = main; /* ok */
main(); /* ok */
}
/* WG14 DR481: yes
* Controlling expression of _Generic primary expression
*/
void dr481(void) {
/* The controlling expression undergoes lvalue to rvalue conversion, and that
* performs array decay and strips qualifiers.
*/
(void)_Generic("bla", char *: "blu");
(void)_Generic((int const){ 0 }, int: "blu"); /* c89only-warning {{compound literals are a C99-specific feature}} */
(void)_Generic(+(int const){ 0 }, int: "blu"); /* c89only-warning {{compound literals are a C99-specific feature}} */
(void)_Generic("bla", /* expected-error {{controlling expression type 'char *' not compatible with any generic association type}} */
char[4]: "blu"); /* expected-warning {{due to lvalue conversion of the controlling expression, association of type 'char[4]' will never be selected because it is of array type}} */
(void)_Generic((int const){ 0 }, /* expected-error {{controlling expression type 'int' not compatible with any generic association type}}
c89only-warning {{compound literals are a C99-specific feature}}
*/
int const: "blu"); /* expected-warning {{due to lvalue conversion of the controlling expression, association of type 'const int' will never be selected because it is qualified}} */
(void)_Generic(+(int const){ 0 }, /* expected-error {{controlling expression type 'int' not compatible with any generic association type}}
c89only-warning {{compound literals are a C99-specific feature}}
*/
int const: "blu"); /* expected-warning {{due to lvalue conversion of the controlling expression, association of type 'const int' will never be selected because it is qualified}} */
}
/* WG14 DR489: partial
* Integer Constant Expression
*
* The DR is about whether unevaluated operands have to follow the same
* restrictions as the rest of the expression in an ICE, and according to the
* committee, they do.
*/
void dr489(void) {
struct S {
int bit : 12 || 1.0f; /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}} */
};
enum E {
Val = 0 && 1.0f /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}} */
};
int i;
/* FIXME: mentioning the 'aligned' attribute is confusing, but also, should
* this be folded as an ICE as a GNU extension? GCC does not fold it.
*/
_Alignas(0 ? i++ : 8) char c; /* expected-error {{'aligned' attribute requires integer constant}} */
/* FIXME: this should get the constant folding diagnostic as this is not a
* valid ICE because the floating-point constants are not the immediate
* operand of a cast. It should then also get a diagnostic about trying to
* declare a VLA with static storage duration and the C99 extension warning
* for VLAs in C89.
*/
static int vla[sizeof(1.0f + 1.0f)];
int val[5] = { [1 ? 0 : i--] = 12 }; /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
c89only-warning {{designated initializers are a C99 feature}}
*/
/* FIXME: this should be the constant folding diagnostic as this is not a
* valid ICE because of the / operator.
*/
_Static_assert(sizeof(0 / 0), "");
/* FIXME: this should also get the constant folding diagnostic as this is not
* a valid ICE because of the = operator.
*/
(void)_Generic(i = 12, int : 0); /* expected-warning {{expression with side effects has no effect in an unevaluated context}} */
switch (i) {
case (int)0.0f: break; /* okay, a valid ICE */
/* FIXME: this should be accepted in C23 and up without a diagnostic, as C23
* added compound literals to the allowed list of things in an ICE. The
* diagnostic is correct for C17 and earlier though.
*/
case (int){ 2 }: break; /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
c89only-warning {{compound literals are a C99-specific feature}}
*/
case 12 || main(): break; /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}} */
}
}
/* WG14 DR492: yes
* Named Child struct-union with no Member
*/
struct dr492_t {
union U11 { /* expected-warning {{declaration does not declare anything}} */
int m11;
float m12;
};
int m13;
} dr492;
/* WG14 DR496: yes
* offsetof questions
*/
void dr496(void) {
struct A { int n, a [2]; };
struct B { struct A a; };
struct C { struct A a[1]; };
/* Array access & member access expressions are now valid. */
_Static_assert(__builtin_offsetof(struct B, a.n) == 0, "");
/* First int below is for 'n' and the second int is for 'a[0]'; this presumes
* there is no padding involved.
*/
_Static_assert(__builtin_offsetof(struct B, a.a[1]) == sizeof(int) + sizeof(int), "");
/* However, we do not support using the -> operator to access a member, even
* if that would be a valid expression. FIXME: GCC accepts this, perhaps we
* should as well.
*/
(void)__builtin_offsetof(struct C, a->n); /* expected-error {{expected ')'}} \
expected-note {{to match this '('}}
*/
/* The DR asked a question about whether defining a new type within offsetof
* is allowed. C23 N2350 had made this explicitly undefined behavior, but this
* was later overturned when C23 DE-137 was accepted, making it well-formed.
*
* Additionally, GCC and Clang both support it as an extension in pre-C23
* mode.
*/
(void)__builtin_offsetof(struct S { int a; }, a); /* pre-c23-warning{{defining a type within '__builtin_offsetof' is a C23 extension}} */
}
/* WG14 DR499: yes
* Anonymous structure in union behavior
*/
void dr499(void) {
union U {
struct {
char B1;
char B2;
char B3;
char B4;
};
int word;
} u;
/* Validate that B1, B2, B3, and B4 do not have overlapping storage, only the
* anonymous structure and 'word' overlap.
*/
_Static_assert(__builtin_offsetof(union U, B1) == 0, "");
_Static_assert(__builtin_offsetof(union U, B2) == 1, "");
_Static_assert(__builtin_offsetof(union U, B3) == 2, "");
_Static_assert(__builtin_offsetof(union U, B4) == 3, "");
_Static_assert(__builtin_offsetof(union U, word) == 0, "");
}
|