================
@@ -0,0 +1,456 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c23 -pedantic -Wall -Wno-comment 
-verify=both,c23 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c17 -pedantic -Wall -Wno-comment 
-Wno-c23-extensions -verify=both,c17 %s
+
+/* WG14 N3037:
+ * Improved tag compatibility
+ *
+ * Identical tag types have always been compatible across TU boundaries. This
+ * paper made identical tag types compatible within the same TU.
+ */
+
+struct foo { int a; } p;
+
+void baz(struct foo f); // c17-note {{passing argument to parameter 'f' here}}
+
+void bar(void) {
+  struct foo { int a; } q = {};
+  baz(q); // c17-error {{passing 'struct foo' to parameter of incompatible 
type 'struct foo'}}
+}
+
+#define PRODUCT(A ,B) struct prod { A a; B b; }                   // 
expected-note 2 {{expanded from macro 'PRODUCT'}}
+#define SUM(A, B) struct sum { _Bool flag; union { A a; B b; }; } // 
expected-note 2 {{expanded from macro 'SUM'}}
+
+void func1(PRODUCT(int, SUM(float, double)) x); // both-warning {{declaration 
of 'struct prod' will not be visible outside of this function}} \
+                                                   both-warning {{declaration 
of 'struct sum' will not be visible outside of this function}} \
+                                                   c17-note {{passing argument 
to parameter 'x' here}}
+void func2(PRODUCT(int, SUM(float, double)) y) { // both-warning {{declaration 
of 'struct prod' will not be visible outside of this function}} \
+                                                    both-warning {{declaration 
of 'struct sum' will not be visible outside of this function}}
+  func1(y); // c17-error {{passing 'struct prod' to parameter of incompatible 
type 'struct prod'}}
+}
+
+struct foop { struct { int x; }; }; // c17-note {{previous definition is here}}
+struct foop { struct { int x; }; }; // c17-error {{redefinition of 'foop'}}
+union barp { int x; float y; };     // c17-note {{previous definition is here}}
+union barp { int x; float y; };     // c17-error {{redefinition of 'barp'}}
+typedef struct q { int x; } q_t;    // c17-note 2 {{previous definition is 
here}}
+typedef struct q { int x; } q_t;    // c17-error {{redefinition of 'q'}} \
+                                       c17-error-re {{typedef redefinition 
with different types ('struct (unnamed struct at {{.*}})' vs 'struct q')}}
+void func3(void) {
+  struct S { int x; };       // c17-note {{previous definition is here}}
+  struct T { struct S s; };  // c17-note {{previous definition is here}}
+  struct S { int x; };       // c17-error {{redefinition of 'S'}}
+  struct T { struct S s; };  // c17-error {{redefinition of 'T'}}
+}
+
+struct food { int (*p)[3]; }; // c23-note {{field 'p' has type 'int (*)[3]' 
here}} \
+                                 c17-note {{previous definition is here}}
+struct food { int (*p)[]; };  // c23-error {{type 'struct food' has 
incompatible definitions}} \
----------------
Sirraide wrote:

Are these structurally equivalent?
```c
struct s { int x[]; };
struct s { int x[0]; };
```

https://github.com/llvm/llvm-project/pull/132939
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to