aboutsummaryrefslogtreecommitdiff
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/C/C2x/n2350.c74
-rw-r--r--clang/test/C/drs/dr4xx.c14
-rw-r--r--clang/test/CXX/drs/dr4xx.cpp6
-rw-r--r--clang/test/CodeGen/offsetof.c4
-rw-r--r--clang/test/Parser/declarators.c4
-rw-r--r--clang/test/Sema/offsetof.c19
-rw-r--r--clang/test/SemaCXX/offsetof.cpp15
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);
+}