[C23][N3006] Documented behavior of underspecified object declaration… · llvm/llvm-project@b896d26 (original) (raw)

``

1

`+

// RUN: %clang_cc1 -std=c23 -verify %s

`

``

2

+

``

3

`+

/* WG14 N3006: Yes

`

``

4

`+

`

``

5

`+

*/

`

``

6

+

``

7

`+

void struct_test(void) {

`

``

8

`+

struct S1 { int x, y; }; // expected-note {{field 'x' has type 'int' here}}

`

``

9

+

``

10

`+

auto normal_struct = (struct S1){ 1, 2 };

`

``

11

`+

auto normal_struct2 = (struct S1) { .x = 1, .y = 2 };

`

``

12

`+

auto underspecified_struct = (struct S2 { int x, y; }){ 1, 2 };

`

``

13

`+

auto underspecified_struct_redef = (struct S1 { char x, y; }){ 'A', 'B'}; // expected-error {{type 'struct S1' has incompatible definitions}} \

`

``

14

`+

expected-error {{cannot use 'auto' with array in C}} \

`

``

15

`+

expected-note {{field 'x' has type 'char' here}}

`

``

16

`+

auto underspecified_empty_struct = (struct S3 { }){ };

`

``

17

`+

auto zero_init_struct = (struct S4 { int x; }){ 0 };

`

``

18

`+

int field_struct = (struct S5 { int y; }){ 0 }.y;

`

``

19

`+

}

`

``

20

+

``

21

`+

void union_test(void) {

`

``

22

`+

union U1 { int a; double b; }; // expected-note {{field 'a' has type 'int' here}}

`

``

23

+

``

24

`+

auto normal_union_int = (union U1){ .a = 12 };

`

``

25

`+

auto normal_union_double = (union U1){ .b = 2.4 };

`

``

26

`+

auto underspecified_union = (union U2 { int a; double b; }){ .a = 34 };

`

``

27

`+

auto underspecified_union_redef = (union U1 { char a; double b; }){ .a = 'A' }; // expected-error {{type 'union U1' has incompatible definitions}} \

`

``

28

`+

expected-error {{cannot use 'auto' with array in C}} \

`

``

29

`+

expected-note {{field 'a' has type 'char' here}}

`

``

30

`+

auto underspecified_empty_union = (union U3 { }){ };

`

``

31

`+

}

`

``

32

+

``

33

`+

void enum_test(void) {

`

``

34

`+

enum E1 { FOO, BAR }; // expected-note {{enumerator 'BAR' with value 1 here}}

`

``

35

+

``

36

`+

auto normal_enum_foo = (enum E1){ FOO };

`

``

37

`+

auto normal_enum_bar = (enum E1){ BAR };

`

``

38

`+

auto underspecified_enum = (enum E2 { BAZ, QUX }){ BAZ };

`

``

39

`+

auto underspecified_enum_redef = (enum E1 { ONE, TWO }){ ONE }; // expected-error {{type 'enum E1' has incompatible definitions}} \

`

``

40

`+

expected-error {{cannot use 'auto' with array in C}} \

`

``

41

`+

expected-note {{enumerator 'ONE' with value 0 here}}

`

``

42

`+

auto underspecified_empty_enum = (enum E3 { }){ }; // expected-error {{use of empty enum}}

`

``

43

`+

auto underspecified_undeclared_enum = (enum E4){ FOO }; // expected-error {{variable has incomplete type 'enum E4'}} \

`

``

44

`+

expected-note {{forward declaration of 'enum E4'}}

`

``

45

`+

}

`

``

46

+

``

47

`+

void constexpr_test(void) {

`

``

48

`+

constexpr auto ce_struct = (struct S1){ 1, 2 }; // expected-error {{variable has incomplete type 'struct S1'}} \

`

``

49

`+

expected-note {{forward declaration of 'struct S1'}}

`

``

50

`+

constexpr auto ce_struct_zero_init = (struct S2 { int x; }){ 0 };

`

``

51

`+

constexpr int ce_struct_field = (struct S3 { int y; }){ 0 }.y;

`

``

52

`+

constexpr auto ce_union = (union U1){ .a = 12 }; // expected-error {{variable has incomplete type 'union U1'}} \

`

``

53

`+

expected-note {{forward declaration of 'union U1'}}

`

``

54

+

``

55

`+

constexpr auto ce_enum = (enum E1 { BAZ, QUX }){ BAZ };

`

``

56

`+

constexpr auto ce_empty_enum = (enum E2){ FOO }; // expected-error {{use of undeclared identifier 'FOO'}}

`

``

57

`+

}

`

``

58

+

``

59

`+

void self_reference_test(void) {

`

``

60

`+

constexpr int i = i; // expected-error {{constexpr variable 'i' must be initialized by a constant expression}} \

`

``

61

`+

expected-note {{read of object outside its lifetime is not allowed in a constant expression}}

`

``

62

`+

auto j = j; // expected-error {{variable 'j' declared with deduced type 'auto' cannot appear in its own initializer}}

`

``

63

`+

}

`

``

64

+

``

65

`+

void redefinition_test(void) {

`

``

66

`+

const struct S { int x; } s; // expected-warning {{default initialization of an object of type 'const struct S' leaves the object uninitialized}} \

`

``

67

`+

expected-note {{previous definition is here}}

`

``

68

`+

constexpr struct S s = {0}; // expected-error {{redefinition of 's'}}

`

``

69

`+

}

`

``

70

+

``

71

`+

void declaring_an_underspecified_defied_object_test(void) {

`

``

72

`+

struct S { int x, y; };

`

``

73

`+

constexpr int i = (struct T { int a, b; }){0, 1}.a;

`

``

74

+

``

75

`+

struct T t = { 1, 2 };

`

``

76

`+

}

`

``

77

+

``

78

`+

void constexpr_complience_test(void) {

`

``

79

`+

int x = (struct Foo { int x; }){ 0 }.x;

`

``

80

`+

constexpr int y = (struct Bar { int x; }){ 0 }.x;

`

``

81

`+

}

`

``

82

+

``

83

`+

void builtin_functions_test(void) {

`

``

84

`+

constexpr typeof(struct s *) x = 0;

`

``

85

`+

auto so = sizeof(struct S {});

`

``

86

`+

auto to = (typeof(struct S {})){};

`

``

87

`+

}

`

``

88

+

``

89

`+

void misc_test(void) {

`

``

90

`+

constexpr struct S { int a, b; } y = { 0 };

`

``

91

`+

constexpr int a = 0, b = 0;

`

``

92

`+

auto c = (struct T { int x, y; }){0, 0};

`

``

93

`+

auto s2 = ({struct T { int x; } s = {}; s.x; });

`

``

94

`+

auto s3 = ((struct {}){},0); // expected-warning {{left operand of comma operator has no effect}}

`

``

95

`+

constexpr int (*fp)(struct X { int x; } val) = 0;

`

``

96

`+

auto v = (void (*)(int y))0;

`

``

97

`+

}

`

``

98

+

``

99

`+

void misc_struct_test(void) {

`

``

100

`+

constexpr struct {

`

``

101

`+

int a;

`

``

102

`+

} a = {};

`

``

103

+

``

104

`+

constexpr struct {

`

``

105

`+

int b;

`

``

106

`+

} b = (struct S { int x; }){ 0 }; // expected-error-re {{initializing 'const struct (unnamed struct at {{.*}}n3006.c:104:13)' with an expression of incompatible type 'struct S'}}

`

``

107

+

``

108

`+

auto z = ({

`

``

109

`+

int a = 12;

`

``

110

`+

struct {} s;

`

``

111

`+

a;

`

``

112

`+

});

`

``

113

`+

}

`