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