aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-11-17 02:26:46 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-11-19 20:50:38 +0100
commit64003b0b9741888cd801e8822b3adb421876b39f (patch)
treea2cd53b3c9db1e2bdcab91b0893ee463654708c3
parent233d4e17c544e1de252aed8f409630599104dbc7 (diff)
downloadsparse-64003b0b9741888cd801e8822b3adb421876b39f.tar.gz
add tests for function attributes
Function attributes need to be parsed differently than the usual specifiers. For example, in code like: #define __noreturn __attribute__((noreturn)) __noreturn void foo(int a); the __noreturn attribute should apply to the function type, while a specifier like 'const' would apply to its return type. It's even more clear when function pointers are involved: __noreturn void (*fptr)(void); here too, the attribute should be applied to the function type, not the its return type, nor to the declared pointer type. Add some testcases to cover some of the situations concerning the parsing of these function pointers. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--validation/attr-visible.c13
-rw-r--r--validation/attr-visible2.c10
-rw-r--r--validation/bitwise-function-pointer.c17
-rw-r--r--validation/function-attribute-inner.c10
-rw-r--r--validation/function-attribute-omitted.c14
-rw-r--r--validation/function-attribute-pointer.c34
-rw-r--r--validation/function-attribute-void-ptr.c14
-rw-r--r--validation/function-attribute.c15
-rw-r--r--validation/pure-function.c17
9 files changed, 134 insertions, 10 deletions
diff --git a/validation/attr-visible.c b/validation/attr-visible.c
new file mode 100644
index 00000000..38ee8575
--- /dev/null
+++ b/validation/attr-visible.c
@@ -0,0 +1,13 @@
+#define __visible __attribute__((externally_visible))
+
+__visible void foo(void)
+{
+}
+
+int flag __visible;
+
+/*
+ * check-name: attr-visible
+ * check-command: sparse -Wdecl $file
+ * check-known-to-fail
+ */
diff --git a/validation/attr-visible2.c b/validation/attr-visible2.c
new file mode 100644
index 00000000..62949b47
--- /dev/null
+++ b/validation/attr-visible2.c
@@ -0,0 +1,10 @@
+#define __visible __attribute__((externally_visible))
+
+int flag __visible;
+int arr[2] __visible;
+
+/*
+ * check-name: attr-visible-after
+ * check-command: sparse -Wdecl $file
+ * check-known-to-fail
+ */
diff --git a/validation/bitwise-function-pointer.c b/validation/bitwise-function-pointer.c
new file mode 100644
index 00000000..544f2fc0
--- /dev/null
+++ b/validation/bitwise-function-pointer.c
@@ -0,0 +1,17 @@
+#define __bitwise __attribute__((bitwise))
+
+typedef unsigned int __bitwise t;
+
+unsigned int fun(void);
+
+static t (*ptr)(void) = fun;
+
+/*
+ * check-name: bitwise-function-pointer
+ *
+ * check-error-start
+bitwise-function-pointer.c:7:25: warning: incorrect type in initializer (different base types)
+bitwise-function-pointer.c:7:25: expected restricted t ( *static [toplevel] ptr )( ... )
+bitwise-function-pointer.c:7:25: got unsigned int ( * )( ... )
+ * check-error-end
+ */
diff --git a/validation/function-attribute-inner.c b/validation/function-attribute-inner.c
new file mode 100644
index 00000000..178c7c01
--- /dev/null
+++ b/validation/function-attribute-inner.c
@@ -0,0 +1,10 @@
+#define __noreturn __attribute__((__noreturn__))
+
+void __noreturn fun(void);
+
+_Static_assert([void (__noreturn *)(void)] == [typeof(&fun)], "");
+
+/*
+ * check-name: function-attribute-inner
+ * check-known-to-fail
+ */
diff --git a/validation/function-attribute-omitted.c b/validation/function-attribute-omitted.c
new file mode 100644
index 00000000..43b301d8
--- /dev/null
+++ b/validation/function-attribute-omitted.c
@@ -0,0 +1,14 @@
+#define __pure __attribute__((pure))
+#define __noreturn __attribute__((noreturn))
+
+
+int __pure p(int i);
+int p(int i) { return i; }
+
+void __noreturn n(void);
+void n(void) { while (1) ; }
+
+/*
+ * check-name: function-attribute-omitted
+ * check-known-to-fail
+ */
diff --git a/validation/function-attribute-pointer.c b/validation/function-attribute-pointer.c
new file mode 100644
index 00000000..27f43bfb
--- /dev/null
+++ b/validation/function-attribute-pointer.c
@@ -0,0 +1,34 @@
+#define __noreturn __attribute__((__noreturn__))
+
+void set_die(void (*)(void));
+void set_die_nr(__noreturn void (*)(void));
+
+void die(void);
+void __noreturn die_nr(void);
+
+static void foo(void)
+{
+ set_die(die);
+ set_die(die_nr);
+ set_die_nr(die_nr);
+ set_die_nr(die);
+
+ void (*fptr0)(void) = die;
+ void (*fptr1)(void) = die_nr;
+ __noreturn void (*fptr3)(void) = die_nr;
+ __noreturn void (*fptr2)(void) = die;
+}
+
+/*
+ * check-name: function-attribute-pointer
+ * check-known-to-fail
+ *
+ * check-error-start
+function-attribute-pointer.c:14:20: warning: incorrect type in argument 1 (different modifiers)
+function-attribute-pointer.c:14:20: expected void ( [noreturn] * )( ... )
+function-attribute-pointer.c:14:20: got void ( * )( ... )
+function-attribute-pointer.c:19:42: warning: incorrect type in initializer (different modifiers)
+function-attribute-pointer.c:19:42: expected void ( [noreturn] *fptr2 )( ... )
+function-attribute-pointer.c:19:42: got void ( * )( ... )
+ * check-error-end
+ */
diff --git a/validation/function-attribute-void-ptr.c b/validation/function-attribute-void-ptr.c
new file mode 100644
index 00000000..0092b63c
--- /dev/null
+++ b/validation/function-attribute-void-ptr.c
@@ -0,0 +1,14 @@
+#define __noreturn __attribute__((__noreturn__))
+
+void fun(void *);
+void __noreturn die(void);
+
+static void foo(void)
+{
+ void *ptr = die;
+ fun(die);
+}
+
+/*
+ * check-name: function-attribute-void-ptr
+ */
diff --git a/validation/function-attribute.c b/validation/function-attribute.c
index 0f2c7592..2be180c4 100644
--- a/validation/function-attribute.c
+++ b/validation/function-attribute.c
@@ -1,17 +1,20 @@
#define __pure __attribute__((pure))
-struct s {
- int x;
-};
-static __pure struct s *grab(struct s *ptr)
+static __pure int funi(int val)
+{
+ return val;
+}
+
+static __pure int *funp(int *ptr)
{
return ptr;
}
-static void foo(struct s *ptr)
+static void foo(int val, int *ptr)
{
- struct s *ptr = grab(ptr);
+ int nbr = funi(val);
+ int *res = funp(ptr);
}
/*
diff --git a/validation/pure-function.c b/validation/pure-function.c
index 04bb85e4..9692cc84 100644
--- a/validation/pure-function.c
+++ b/validation/pure-function.c
@@ -1,16 +1,25 @@
-static __attribute__((__pure__)) int pure1(void)
+static __attribute__((__pure__)) int pure_int(int v)
{
- int i = 0;
+ int i = v;
return i;
}
-static __attribute__((__pure__)) void *pure2(void)
+static __attribute__((__pure__)) void *pure_ptr(void *p)
{
- void *i = (void *)0;
+ void *i = p;
return i;
}
+static void foo(int v, void *p)
+{
+ int val = pure_int(v);
+ void *ptr = pure_ptr(p);
+
+ (void)val;
+ (void)ptr;
+}
+
/*
* check-name: Pure function attribute
*/