|
| 1 | +// RUN: %clang_cc1 -std=c2x -verify %s |
| 2 | + |
| 3 | +/* WG14 N3006: Full |
| 4 | + * Underspecified object declarations |
| 5 | + */ |
| 6 | + |
| 7 | +struct S1 { int x, y; }; // expected-note {{previous definition is here}} |
| 8 | +union U1 { int a; double b; }; // expected-note {{previous definition is here}} |
| 9 | +enum E1 { FOO, BAR }; // expected-note {{previous definition is here}} |
| 10 | + |
| 11 | +auto normal_struct = (struct S1){ 1, 2 }; |
| 12 | +auto normal_struct2 = (struct S1) { .x = 1, .y = 2 }; |
| 13 | +auto underspecified_struct = (struct S2 { int x, y; }){ 1, 2 }; // expected-error {{'struct S2' is defined as an underspecified object initializer}} |
| 14 | +auto underspecified_struct_redef = (struct S1 { char x, y; }){ 'A', 'B'}; // expected-error {{redefinition of 'S1'}} |
| 15 | +auto underspecified_empty_struct = (struct S3 { }){ }; // expected-error {{'struct S3' is defined as an underspecified object initializer}} |
| 16 | + |
| 17 | +auto normal_union_int = (union U1){ .a = 12 }; |
| 18 | +auto normal_union_double = (union U1){ .b = 2.4 }; |
| 19 | +auto underspecified_union = (union U2 { int a; double b; }){ .a = 34 }; // expected-error {{'union U2' is defined as an underspecified object initializer}} |
| 20 | +auto underspecified_union_redef = (union U1 { char a; double b; }){ .a = 'A' }; // expected-error {{redefinition of 'U1'}} |
| 21 | +auto underspecified_empty_union = (union U3 { }){ }; // expected-error {{'union U3' is defined as an underspecified object initializer}} |
| 22 | + |
| 23 | +auto normal_enum_foo = (enum E1){ FOO }; |
| 24 | +auto normal_enum_bar = (enum E1){ BAR }; |
| 25 | +auto underspecified_enum = (enum E2 { BAZ, QUX }){ BAZ }; // expected-error {{'enum E2' is defined as an underspecified object initializer}} |
| 26 | +auto underspecified_enum_redef = (enum E1 { ONE, TWO }){ ONE }; // expected-error {{redefinition of 'E1'}} |
| 27 | +auto underspecified_empty_enum = (enum E3 { }){ }; // expected-error {{'enum E3' is defined as an underspecified object initializer}} \ |
| 28 | + expected-error {{use of empty enum}} |
| 29 | +void constexpr_test() { |
| 30 | + constexpr auto ce_struct = (struct S1){ 1, 2 }; |
| 31 | + constexpr auto ce_union = (union U1){ .a = 12 }; |
| 32 | + constexpr auto ce_enum = (enum E1){ FOO }; |
| 33 | +} |
| 34 | + |
| 35 | +void trivial_test() { |
| 36 | + constexpr int i = i; // expected-error {{constexpr variable 'i' must be initialized by a constant expression}} \ |
| 37 | + expected-note {{read of object outside its lifetime is not allowed in a constant expression}} |
| 38 | + auto j = j; // expected-error {{variable 'j' declared with deduced type 'auto' cannot appear in its own initializer}} |
| 39 | +} |
| 40 | + |
| 41 | +void double_definition_test() { |
| 42 | + const struct S { int x; } s; // expected-note {{previous definition is here}} |
| 43 | + constexpr struct S s = {0}; // expected-error {{redefinition of 's'}} |
| 44 | +} |
| 45 | + |
| 46 | +void declaring_an_underspecified_defied_object_test() { |
| 47 | + struct S { int x, y; }; |
| 48 | + constexpr int i = (struct T { int a, b; }){0, 1}.a; // expected-error {{'struct T' is defined as an underspecified object initializer}} \ |
| 49 | + FIXME: `constexpr variable 'i' must be initialized by a constant expression` shoud appear |
| 50 | + |
| 51 | + struct T t = { 1, 2 }; // TODO: Should this be diagnosed as an invalid declaration? |
| 52 | +} |
| 53 | + |
| 54 | +void constexpr_complience_test() { |
| 55 | + int x = (struct Foo { int x; }){ 0 }.x; // expected-error {{'struct Foo' is defined as an underspecified object initializer}} |
| 56 | + constexpr int y = (struct Bar { int x; }){ 0 }.x; // expected-error {{'struct Bar' is defined as an underspecified object initializer}} |
| 57 | +} |
| 58 | + |
| 59 | +void special_test() { |
| 60 | + constexpr typeof(struct s *) x = 0; // FIXME: declares `s` which is not an ordinary identifier |
| 61 | + constexpr struct S { int a, b; } y = { 0 }; // FIXME: declares `S`, `a`, and `b`, none of which are ordinary identifiers |
| 62 | + constexpr int a = 0, b = 0; |
| 63 | + auto c = (struct T { int x, y; }){0, 0}; // expected-error {{'struct T' is defined as an underspecified object initializer}} |
| 64 | + constexpr int (*fp)(struct X { int x; } val) = 0; // expected-warning {{declaration of 'struct X' will not be visible outside of this function}} \ |
| 65 | + FIXME: declares `X` and `x` which are not ordinary identifiers |
| 66 | +} |
0 commit comments