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