llvm-project/clang/test/Sema/bpf-attr-preserve-access-in...

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

49 lines
1.3 KiB
C
Raw Normal View History

[BPF] Add preserve_access_index attribute for record definition This is a resubmission for the previous reverted commit 943436040121 with the same subject. This commit fixed the segfault issue and addressed additional review comments. This patch introduced a new bpf specific attribute which can be added to struct or union definition. For example, struct s { ... } __attribute__((preserve_access_index)); union u { ... } __attribute__((preserve_access_index)); The goal is to simplify user codes for cases where preserve access index happens for certain struct/union, so user does not need to use clang __builtin_preserve_access_index for every members. The attribute has no effect if -g is not specified. When the attribute is specified and -g is specified, any member access defined by that structure or union, including array subscript access and inner records, will be preserved through __builtin_preserve_{array,struct,union}_access_index() IR intrinsics, which will enable relocation generation in bpf backend. The following is an example to illustrate the usage: -bash-4.4$ cat t.c #define __reloc__ __attribute__((preserve_access_index)) struct s1 { int c; } __reloc__; struct s2 { union { struct s1 b[3]; }; } __reloc__; struct s3 { struct s2 a; } __reloc__; int test(struct s3 *arg) { return arg->a.b[2].c; } -bash-4.4$ clang -target bpf -g -S -O2 t.c A relocation with access string "0:0:0:0:2:0" will be generated representing access offset of arg->a.b[2].c. forward declaration with attribute is also handled properly such that the attribute is copied and populated in real record definition. Differential Revision: https://reviews.llvm.org/D69759
2019-11-02 13:16:59 +08:00
// RUN: %clang_cc1 -x c -triple bpf-pc-linux-gnu -dwarf-version=4 -fsyntax-only -verify %s
#define __reloc__ __attribute__((preserve_access_index))
#define __err_reloc__ __attribute__((preserve_access_index(0)))
struct t1 {
int a;
int b[4];
int c:1;
} __reloc__;
union t2 {
int a;
int b[4];
int c:1;
} __reloc__;
struct t3 {
int a;
} __err_reloc__; // expected-error {{'preserve_access_index' attribute takes no arguments}}
struct t4 {
union {
int a;
char b[5];
};
struct {
int c:1;
} __reloc__;
int d;
} __reloc__;
struct __reloc__ p;
struct __reloc__ q;
struct p {
int a;
};
int a __reloc__; // expected-error {{'preserve_access_index' attribute only applies to structs, unions, and classes}}
struct s *p __reloc__; // expected-error {{'preserve_access_index' attribute only applies to structs, unions, and classes}}
void invalid1(const int __reloc__ *arg) {} // expected-error {{'preserve_access_index' attribute only applies to structs, unions, and classes}}
void invalid2() { const int __reloc__ *arg; } // expected-error {{'preserve_access_index' attribute only applies to structs, unions, and classes}}
int valid3(struct t4 *arg) { return arg->a + arg->b[3] + arg->c + arg->d; }
int valid4(void *arg) {
struct local_t { int a; int b; } __reloc__;
return ((struct local_t *)arg)->b;
}