diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2021-02-08 00:46:01 +0100 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2021-02-25 00:18:26 +0100 |
| commit | eb55532d516c93a59946489114422c587a7cd0cd (patch) | |
| tree | 74e537b7d87c64b2bf236c300f2a774d34999ff0 /validation | |
| parent | 89a73382b14904cd762529a79ca74e8c2b389dbc (diff) | |
| download | sparse-dev-eb55532d516c93a59946489114422c587a7cd0cd.tar.gz | |
expand __builtin_object_size()
__builtin_object_size() is one of these builtins that must be
somehow expanded because it can't possibly be implemented at
runtime. It's used by the kernel's copy_{to,from}_user() and
the 'fortified' string functions, as well as by userspace's
'checked string/memory functions' like __builtin___memcpy_chk().
So, use the normal builtin expansion interface for this one too.
This gets rid of 2/3 of them when used on the kernel and shaves
~0.5% of the total IR code (with x86's defconfig).
Notes:
1) What is covered is an object symbol, with an optional designator
of arbitrary complexity, ignoring casts and accessed via
an optional chain of simple dereferences. Maybe some access
path need to be added.
2) Anything with dynamic value is currently considered either as
unknown (VLAs, variables or parameters) or left for a later
stage (any function calls, including functions known to allocate
memory given that attribute alloc_size() is not yet supported).
3) It's not totally clear to me when to give up (and thus return
'size unknown') and when things can or must be left to the
simplification phase. This matters because __builtin_object_size()
is relatively often used with __builtin_constant_p().
4) Currently, only type 0 is really supported. Given the way
designators are evaluated and expanded (information is lost because
the expressions are overwritten), to support the other types, the
expansion of __builtin_object_size() should be done during
evaluation itself, much like it's done for sizeof() and
offsetof().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'validation')
| -rw-r--r-- | validation/builtin-objsize-dyn.c | 22 | ||||
| -rw-r--r-- | validation/builtin-objsize0.c | 25 | ||||
| -rw-r--r-- | validation/builtin-objsize1.c | 21 |
3 files changed, 68 insertions, 0 deletions
diff --git a/validation/builtin-objsize-dyn.c b/validation/builtin-objsize-dyn.c new file mode 100644 index 00000000..276c9204 --- /dev/null +++ b/validation/builtin-objsize-dyn.c @@ -0,0 +1,22 @@ +void *alloc(unsigned long)__attribute__((alloc_size(1))); + +_Bool sta(void) +{ + void *ptr = alloc(4); + return __builtin_object_size(ptr, 0) == 4; +} + +_Bool dyn(unsigned long n) +{ + void *ptr = alloc(n); + return __builtin_object_size(ptr, 0) == n; +} + +/* + * check-name: builtin-objsize-dyn + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/builtin-objsize0.c b/validation/builtin-objsize0.c new file mode 100644 index 00000000..9aab2ddd --- /dev/null +++ b/validation/builtin-objsize0.c @@ -0,0 +1,25 @@ +#define bos(O, T) __builtin_object_size(O, T) + +struct s { + char arr[8]; + __INT32_TYPE__ i; + __INT32_TYPE__ padding; +}; + +static struct s s; +static char *p = &s.arr[1]; +static int *q = &s.i; + +int obj_int0(void) { return bos(&s.i, 0) == 8; } +int obj_arr0(void) { return bos(&s.arr[1], 0) == 15; } + +int ptr_int(struct s *p) { return bos(&p->i, 0) == -1; } +int ptr_arr(struct s *p) { return bos(&p->arr[1], 0) == -1; } + +/* + * check-name: builtin-objsize0 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/builtin-objsize1.c b/validation/builtin-objsize1.c new file mode 100644 index 00000000..1f285fc5 --- /dev/null +++ b/validation/builtin-objsize1.c @@ -0,0 +1,21 @@ +#define bos(O, T) __builtin_object_size(O, T) + +struct s { + char arr[8]; + __INT32_TYPE__ i; + __INT32_TYPE__ padding; +}; + +static struct s s; + +int obj_int1(void) { return bos(&s.i, 1) == 4; } +int obj_arr1(void) { return bos(&s.arr[1], 1) == 7; } + +/* + * check-name: builtin-objsize1 + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-returns: 1 + */ |
