1 // RUN: %clang_cc1 %s -triple %itanium_abi_triple -fsyntax-only -verify -Wc++-compat
2
3 // Note: Empty C structs are 4 bytes in the Microsoft ABI.
4
5 struct emp_1 { // expected-warning {{empty struct has size 0 in C, size 1 in C++}}
6 };
7
8 union emp_2 { // expected-warning {{empty union has size 0 in C, size 1 in C++}}
9 };
10
11 struct emp_3 { // expected-warning {{struct has size 0 in C, size 1 in C++}}
12 int : 0;
13 };
14
15 union emp_4 { // expected-warning {{union has size 0 in C, size 1 in C++}}
16 int : 0;
17 };
18
19 struct emp_5 { // expected-warning {{struct has size 0 in C, size 1 in C++}}
20 int : 0;
21 int : 0;
22 };
23
24 union emp_6 { // expected-warning {{union has size 0 in C, size 1 in C++}}
25 int : 0;
26 int : 0;
27 };
28
29 struct emp_7 { // expected-warning {{struct has size 0 in C, size 1 in C++}}
30 struct emp_1 f1;
31 };
32
33 union emp_8 { // expected-warning {{union has size 0 in C, size 1 in C++}}
34 struct emp_1 f1;
35 };
36
37 struct emp_9 { // expected-warning {{struct has size 0 in C, non-zero size in C++}}
38 struct emp_1 f1;
39 union emp_2 f2;
40 };
41
42 // Checks for pointer subtraction (PR15683)
func_1p(struct emp_1 * x)43 struct emp_1 *func_1p(struct emp_1 *x) { return x - 5; }
44
func_1()45 int func_1() {
46 struct emp_1 v[1];
47 return v - v; // expected-warning {{subtraction of pointers to type 'struct emp_1' of zero size has undefined behavior}}
48 }
49
func_2(struct emp_1 * x)50 int func_2(struct emp_1 *x) {
51 return 1 + x - x; // expected-warning {{subtraction of pointers to type 'struct emp_1' of zero size has undefined behavior}}
52 }
53
func_3(struct emp_1 * x,struct emp_1 * y)54 int func_3(struct emp_1 *x, struct emp_1 *y) {
55 return x - y; // expected-warning {{subtraction of pointers to type 'struct emp_1' of zero size has undefined behavior}}
56 }
57
func_4(struct emp_1 * x,const struct emp_1 * y)58 int func_4(struct emp_1 *x, const struct emp_1 *y) {
59 return x - y; // expected-warning {{subtraction of pointers to type 'struct emp_1' of zero size has undefined behavior}}
60 }
61
func_5(volatile struct emp_1 * x,const struct emp_1 * y)62 int func_5(volatile struct emp_1 *x, const struct emp_1 *y) {
63 return x - y; // expected-warning {{subtraction of pointers to type 'struct emp_1' of zero size has undefined behavior}}
64 }
65
func_6()66 int func_6() {
67 union emp_2 v[1];
68 return v - v; // expected-warning {{subtraction of pointers to type 'union emp_2' of zero size has undefined behavior}}
69 }
70
71 struct A; // expected-note {{forward declaration of 'struct A'}}
72
func_7(struct A * x,struct A * y)73 int func_7(struct A *x, struct A *y) {
74 return x - y; // expected-error {{arithmetic on a pointer to an incomplete type 'struct A'}}
75 }
76
func_8(struct emp_1 (* x)[10],struct emp_1 (* y)[10])77 int func_8(struct emp_1 (*x)[10], struct emp_1 (*y)[10]) {
78 return x - y; // expected-warning {{subtraction of pointers to type 'struct emp_1 [10]' of zero size has undefined behavior}}
79 }
80
func_9(struct emp_1 (* x)[],struct emp_1 (* y)[])81 int func_9(struct emp_1 (*x)[], struct emp_1 (*y)[]) {
82 return x - y; // expected-error {{arithmetic on a pointer to an incomplete type 'struct emp_1 []'}}
83 }
84
func_10(int (* x)[0],int (* y)[0])85 int func_10(int (*x)[0], int (*y)[0]) {
86 return x - y; // expected-warning {{subtraction of pointers to type 'int [0]' of zero size has undefined behavior}}
87 }
88