aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/validation
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2021-02-08 00:46:01 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2021-02-25 00:18:26 +0100
commiteb55532d516c93a59946489114422c587a7cd0cd (patch)
tree74e537b7d87c64b2bf236c300f2a774d34999ff0 /validation
parent89a73382b14904cd762529a79ca74e8c2b389dbc (diff)
downloadsparse-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.c22
-rw-r--r--validation/builtin-objsize0.c25
-rw-r--r--validation/builtin-objsize1.c21
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
+ */