diff options
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/C/C2x/n2350.c | 74 | ||||
-rw-r--r-- | clang/test/C/drs/dr4xx.c | 14 | ||||
-rw-r--r-- | clang/test/CXX/drs/dr4xx.cpp | 6 | ||||
-rw-r--r-- | clang/test/CodeGen/offsetof.c | 4 | ||||
-rw-r--r-- | clang/test/Parser/declarators.c | 4 | ||||
-rw-r--r-- | clang/test/Sema/offsetof.c | 19 | ||||
-rw-r--r-- | clang/test/SemaCXX/offsetof.cpp | 15 |
7 files changed, 114 insertions, 22 deletions
diff --git a/clang/test/C/C2x/n2350.c b/clang/test/C/C2x/n2350.c new file mode 100644 index 0000000..93ab507 --- /dev/null +++ b/clang/test/C/C2x/n2350.c @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -fsyntax-only -verify=silent %s +// RUN: %clang_cc1 -fsyntax-only -verify=cpp -x c++ %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c89 -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c99 -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c17 -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c2x -verify %s + +// silent-no-diagnostics + +// Reject definitions in __builtin_offsetof +// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm +int simple(void) { + return __builtin_offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} \ + expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}} + { + int a; + struct B // expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}} + { + int c; + int d; + } x; + }, a); +} + +int anonymous_struct(void) { + return __builtin_offsetof(struct // cpp-error-re {{'(unnamed struct at {{.*}})' cannot be defined in a type specifier}} \ + expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}} + { + int a; + int b; + }, a); +} + +int struct_in_second_param(void) { + struct A { + int a, b; + int x[20]; + }; + return __builtin_offsetof(struct A, x[sizeof(struct B{int a;})]); // cpp-error {{'B' cannot be defined in a type specifier}} \ + expected-warning {{using an array subscript expression within '__builtin_offsetof' is a Clang extension}} +} + + +#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER) + + +int macro(void) { + return offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} \ + expected-warning 2 {{defining a type within 'offsetof' is a Clang extension}} + { + int a; + struct B // verifier seems to think the error is emitted by the macro + // In fact the location of the error is "B" on the line above + { + int c; + int d; + } x; + }, a); +} + +#undef offsetof + +#define offsetof(TYPE, MEMBER) (&((TYPE *)0)->MEMBER) + +// no warning for traditional offsetof as a function-like macro +int * macro_func(void) { + return offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} + { + int a; + int b; + }, a); +} diff --git a/clang/test/C/drs/dr4xx.c b/clang/test/C/drs/dr4xx.c index 768897c..3ad9b17 100644 --- a/clang/test/C/drs/dr4xx.c +++ b/clang/test/C/drs/dr4xx.c @@ -337,12 +337,13 @@ void dr496(void) { * because it references an array of another struct. Clang calculates the * correct offset to each of those fields. */ - _Static_assert(__builtin_offsetof(struct B, a.n) == 0, ""); + _Static_assert(__builtin_offsetof(struct B, a.n) == 0, ""); /* expected-warning {{using a member access expression within '__builtin_offsetof' is a Clang extension}} */ /* First int below is for 'n' and the second int is for 'a[0]'; this presumes * there is no padding involved. */ - _Static_assert(__builtin_offsetof(struct B, a.a[1]) == sizeof(int) + sizeof(int), ""); - + _Static_assert(__builtin_offsetof(struct B, a.a[1]) == sizeof(int) + sizeof(int), ""); /* expected-warning {{using a member access expression within '__builtin_offsetof' is a Clang extension}} + expected-warning {{using an array subscript expression within '__builtin_offsetof' is a Clang extension}} + */ /* However, we do not support using the -> operator to access a member, even * if that would be a valid expression. FIXME: GCC accepts this, perhaps we * should as well. @@ -352,11 +353,10 @@ void dr496(void) { */ /* The DR asked a question about whether defining a new type within offsetof - * is allowed. C2x N2350 made this explicitly undefined behavior, but Clang - * has always supported defining a type in this location, and GCC also - * supports it. + * is allowed. C2x N2350 made this explicitly undefined behavior, but GCC and + * Clang both support it as an extension. */ - (void)__builtin_offsetof(struct S { int a; }, a); + (void)__builtin_offsetof(struct S { int a; }, a); /* expected-warning{{defining a type within '__builtin_offsetof' is a Clang extension}} */ } /* WG14 DR499: yes diff --git a/clang/test/CXX/drs/dr4xx.cpp b/clang/test/CXX/drs/dr4xx.cpp index 3617af8..476d80e 100644 --- a/clang/test/CXX/drs/dr4xx.cpp +++ b/clang/test/CXX/drs/dr4xx.cpp @@ -687,9 +687,9 @@ namespace dr447 { // dr447: yes U<__builtin_offsetof(A, n)>::type a; U<__builtin_offsetof(T, n)>::type b; // expected-error +{{}} expected-warning 0+{{}} // as an extension, we allow the member-designator to include array indices - g(__builtin_offsetof(A, a[0])).h<int>(); - g(__builtin_offsetof(A, a[N])).h<int>(); - U<__builtin_offsetof(A, a[0])>::type c; + g(__builtin_offsetof(A, a[0])).h<int>(); // expected-error {{using an array subscript expression within '__builtin_offsetof' is a Clang extension}} + g(__builtin_offsetof(A, a[N])).h<int>(); // expected-error {{using an array subscript expression within '__builtin_offsetof' is a Clang extension}} + U<__builtin_offsetof(A, a[0])>::type c; // expected-error {{using an array subscript expression within '__builtin_offsetof' is a Clang extension}} U<__builtin_offsetof(A, a[N])>::type d; // expected-error +{{}} expected-warning 0+{{}} } } diff --git a/clang/test/CodeGen/offsetof.c b/clang/test/CodeGen/offsetof.c index c279e22..13b34ea 100644 --- a/clang/test/CodeGen/offsetof.c +++ b/clang/test/CodeGen/offsetof.c @@ -10,3 +10,7 @@ int test(int len) { return __builtin_offsetof(struct sockaddr_un, sun_path[len+1]); } +// Ensure we can form the offset to a structure defined in the first argument +// without crashing or asserting on an invalid declaration (because the +// declaration is actually valid). +void c() { __builtin_offsetof(struct {int b;}, b); } diff --git a/clang/test/Parser/declarators.c b/clang/test/Parser/declarators.c index 464fafe..3af0981 100644 --- a/clang/test/Parser/declarators.c +++ b/clang/test/Parser/declarators.c @@ -80,10 +80,6 @@ struct test9 { struct test10 { int a; } static test10x; struct test11 { int a; } const test11x; -// PR6216 -void test12(void) { - (void)__builtin_offsetof(struct { char c; int i; }, i); -} // rdar://7608537 struct test13 { int a; } (test13x); diff --git a/clang/test/Sema/offsetof.c b/clang/test/Sema/offsetof.c index 3a5ddc4..8fd9ad6 100644 --- a/clang/test/Sema/offsetof.c +++ b/clang/test/Sema/offsetof.c @@ -5,35 +5,38 @@ typedef struct P { int i; float f; } PT; struct external_sun3_core { - unsigned c_regs; + unsigned c_regs; PT X[100]; - + }; +// Ensure the builtin works as a constant expression +int i = offsetof(PT, f); + void swap(void) { int x; x = offsetof(struct external_sun3_core, c_regs); x = __builtin_offsetof(struct external_sun3_core, X[42].f); - + x = __builtin_offsetof(struct external_sun3_core, X[42].f2); // expected-error {{no member named 'f2'}} x = __builtin_offsetof(int, X[42].f2); // expected-error {{offsetof requires struct}} - + int a[__builtin_offsetof(struct external_sun3_core, X) == 4 ? 1 : -1]; int b[__builtin_offsetof(struct external_sun3_core, X[42]) == 340 ? 1 : -1]; int c[__builtin_offsetof(struct external_sun3_core, X[42].f2) == 344 ? 1 : -1]; // expected-error {{no member named 'f2'}} -} +} extern int f(void); -struct s1 { int a; }; +struct s1 { int a; }; int v1 = offsetof (struct s1, a) == 0 ? 0 : f(); -struct s2 { int a; }; +struct s2 { int a; }; int v2 = (int)(&((struct s2 *) 0)->a) == 0 ? 0 : f(); -struct s3 { int a; }; +struct s3 { int a; }; int v3 = __builtin_offsetof(struct s3, a) == 0 ? 0 : f(); // PR3396 diff --git a/clang/test/SemaCXX/offsetof.cpp b/clang/test/SemaCXX/offsetof.cpp index c4b288a..39ea380 100644 --- a/clang/test/SemaCXX/offsetof.cpp +++ b/clang/test/SemaCXX/offsetof.cpp @@ -83,3 +83,18 @@ struct Derived : virtual Base { expected-error {{invalid application of 'offsetof' to a field of a virtual base}} }; } + +int test_definition(void) { + return __builtin_offsetof(struct A // expected-error {{'A' cannot be defined in a type specifier}} + { + int a; + struct B // FIXME: error diagnostic message for nested definitions + // https://reviews.llvm.org/D133574 + // fixme-error{{'A' cannot be defined in '__builtin_offsetof'}} + { + int c; + int d; + }; + B x; + }, a); +} |