xref: /llvm-project/clang/test/C/C23/n2350.c (revision 50c81128de8616117118564eff22cf508cba7848)
1 // RUN: %clang_cc1 -fsyntax-only -verify=silent %s
2 // RUN: %clang_cc1 -fsyntax-only -verify=cpp -x c++ %s
3 // RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -verify %s
4 // RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c89 -verify %s
5 // RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c99 -verify %s
6 // RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c11 -verify %s
7 // RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c17 -verify %s
8 // RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c2x -verify=silent %s
9 
10 // silent-no-diagnostics
11 
12 // Reject definitions in __builtin_offsetof
13 // https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
simple(void)14 int simple(void) {
15   return __builtin_offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} \
16                                         expected-warning {{defining a type within '__builtin_offsetof' is a C23 extension}}
17   {
18     int a;
19     struct B // expected-warning {{defining a type within '__builtin_offsetof' is a C23 extension}}
20     {
21       int c;
22       int d;
23     } x;
24   }, a);
25 }
26 
anonymous_struct(void)27 int anonymous_struct(void) {
28   return __builtin_offsetof(struct // cpp-error-re {{'(unnamed struct at {{.*}})' cannot be defined in a type specifier}} \
29                                       expected-warning {{defining a type within '__builtin_offsetof' is a C23 extension}}
30   {
31     int a;
32     int b;
33   }, a);
34 }
35 
struct_in_second_param(void)36 int struct_in_second_param(void) {
37   struct A {
38     int a, b;
39     int x[20];
40   };
41   return __builtin_offsetof(struct A, x[sizeof(struct B{int a;})]); // cpp-error {{'B' cannot be defined in a type specifier}}
42 }
43 
44 
45 #define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
46 
47 
macro(void)48 int macro(void) {
49   return offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} \
50                               expected-warning 2 {{defining a type within 'offsetof' is a C23 extension}}
51   {
52     int a;
53     struct B // verifier seems to think the error is emitted by the macro
54              // In fact the location of the error is "B" on the line above
55     {
56       int c;
57       int d;
58     } x;
59   }, a);
60 }
61 
62 #undef offsetof
63 
64 #define offsetof(TYPE, MEMBER) (&((TYPE *)0)->MEMBER)
65 
66 // no warning for traditional offsetof as a function-like macro
macro_func(void)67 int * macro_func(void) {
68   return offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}}
69   {
70     int a;
71     int b;
72   }, a);
73 }
74