|
| 1 | +// RUN: %clang_cc1 -std=c2y %s -verify -Wno-gnu-alignof-expression |
| 2 | + |
| 3 | +/* WG14 N3244: Partial |
| 4 | + * Slay Some Earthly Demons I |
| 5 | + * |
| 6 | + * NB: the committee adopted: |
| 7 | + * Annex J Item 21 (including additional change) -- no, we lack explicit documentation |
| 8 | + * Annex J Item 56 -- yes |
| 9 | + * Annex J Item 57 Option 1 -- yes |
| 10 | + * Annex J Item 67 -- no |
| 11 | + * Annex J Item 69 (alternative wording for semantics) -- no |
| 12 | + */ |
| 13 | + |
| 14 | +void reg_array(void) { |
| 15 | + // Decay of an array with the register storage class specifier has gone from |
| 16 | + // explicit undefined behavior to be implementation defined instead. Clang |
| 17 | + // does not support this. |
| 18 | + register int array[10]; |
| 19 | + (void)sizeof(array); // okay |
| 20 | + int *vp = array; // expected-error {{address of register variable requested}} |
| 21 | + int val = array[0]; // expected-error {{address of register variable requested}} |
| 22 | +} |
| 23 | + |
| 24 | +struct F; // expected-note {{forward declaration of 'struct F'}} |
| 25 | +void incomplete_no_linkage(struct F); // okay |
| 26 | +void incomplete_no_linkage(struct F f) { // expected-error {{variable has incomplete type 'struct F'}} |
| 27 | + struct G g; // expected-error {{variable has incomplete type 'struct G'}} \ |
| 28 | + expected-note {{forward declaration of 'struct G'}} |
| 29 | + int i[]; // expected-error {{definition of variable with array type needs an explicit size or an initializer}} |
| 30 | +} |
| 31 | + |
| 32 | +void block_scope_non_extern_func_decl(void) { |
| 33 | + static void f(void); // expected-error {{function declared in block scope cannot have 'static' storage class}} |
| 34 | + extern void g(void); // okay |
| 35 | + __private_extern__ void h(void); // okay |
| 36 | +} |
| 37 | + |
| 38 | +// FIXME: this function should be diagnosed as it is never defined in the TU. |
| 39 | +extern inline void never_defined_extern_inline(void); |
| 40 | + |
| 41 | +// While this declaration is fine because the function is defined within the TU. |
| 42 | +extern inline void is_defined_extern_inline(void); |
| 43 | +extern inline void is_defined_extern_inline(void) {} |
| 44 | + |
| 45 | +int NoAlignmentOnOriginalDecl; |
| 46 | +// FIXME: the original declaration has no alignment specifier, so the |
| 47 | +// declaration below should be diagnosed due to the incompatible alignment |
| 48 | +// specifier. |
| 49 | +_Alignas(8) int NoAlignmentOnOriginalDecl; |
| 50 | +_Static_assert(_Alignof(NoAlignmentOnOriginalDecl) == 8, ""); |
| 51 | + |
| 52 | +_Alignas(8) int AlignmentOnOriginalDecl; // expected-note {{declared with '_Alignas' attribute here}} |
| 53 | +// FIXME: this should be accepted because the redeclaration has no alignment |
| 54 | +// specifier. |
| 55 | +int AlignmentOnOriginalDecl; // expected-error {{'_Alignas' must be specified on definition if it is specified on any declaration}} |
| 56 | +_Static_assert(_Alignof(AlignmentOnOriginalDecl) == 8, ""); |
| 57 | + |
| 58 | +long long CompatibleAlignment; |
| 59 | +_Static_assert(_Alignof(CompatibleAlignment) == _Alignof(long long), ""); |
| 60 | +_Alignas(_Alignof(long long)) long long CompatibleAlignment; // Okay, alignment is the same as the implied alignment |
| 61 | + |
| 62 | +_Alignas(_Alignof(long long)) long long CompatibleAlignment2; // expected-note {{declared with '_Alignas' attribute here}} |
| 63 | +// FIXME: this should be accepted because the redeclaration has no alignment |
| 64 | +// specifier. |
| 65 | +long long CompatibleAlignment2; // expected-error {{'_Alignas' must be specified on definition if it is specified on any declaration}} |
| 66 | + |
| 67 | +// FIXME: this should be accepted because the definition specifies the |
| 68 | +// alignment and a subsequent declaration does not specify any alignment. |
| 69 | +_Alignas(8) long long DefnWithInit = 12; // expected-note {{declared with '_Alignas' attribute here}} |
| 70 | +long long DefnWithInit; // expected-error {{'_Alignas' must be specified on definition if it is specified on any declaration}} |
| 71 | + |
| 72 | +// This is accepted because the definition has an alignment specifier and the |
| 73 | +// subsequent redeclaration does not specify an alignment. |
| 74 | +_Alignas(8) long long DefnWithInit2 = 12; |
| 75 | +extern long long DefnWithInit2; |
| 76 | + |
| 77 | +// FIXME: this should be accepted because the definition specifies the |
| 78 | +// alignment and a subsequent declaration specifies a compatible alignment. |
| 79 | +long long DefnWithInit3 = 12; // expected-error {{'_Alignas' must be specified on definition if it is specified on any declaration}} |
| 80 | +_Alignas(_Alignof(long long)) long long DefnWithInit3; // expected-note {{declared with '_Alignas' attribute here}} |
| 81 | + |
| 82 | +_Alignas(8) int Mismatch; // expected-note {{previous declaration is here}} |
| 83 | +_Alignas(16) int Mismatch; // expected-error {{redeclaration has different alignment requirement (16 vs 8)}} |
0 commit comments