aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/validation
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-11-03 21:49:15 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-03-24 10:51:35 +0100
commit79f7ac984473d031dfb9cef00119c2d542d0d4a6 (patch)
tree5af6e6713ee40d83b572e96897b644e1938b4c5e /validation
parentbff9b106e8fc02ab89da5fc7bf6d5e05b676da13 (diff)
downloadsparse-dev-79f7ac984473d031dfb9cef00119c2d542d0d4a6.tar.gz
add support for GCC's __auto_type
Despite the similarity with typeof, the approach taken here is relatively different. A specific symbol type (SYM_TYPEOF) is not used, instead a new flag is added to decl_state, another one in the declared symbol and a new internal type is used: 'autotype_ctype'. It's this new internal type that will be resolved to the definitive type at evalution time. It seems to be working pretty well, maybe because it hasn't been tested well enough. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'validation')
-rw-r--r--validation/autotype-ko.c45
-rw-r--r--validation/autotype.c55
2 files changed, 100 insertions, 0 deletions
diff --git a/validation/autotype-ko.c b/validation/autotype-ko.c
new file mode 100644
index 00000000..5b6cd708
--- /dev/null
+++ b/validation/autotype-ko.c
@@ -0,0 +1,45 @@
+__auto_type u; // KO: no initializer
+__auto_type r[2] = { 0, 1 }; // KO: not a plain identifier
+__auto_type foo(void) { } // KO: not a plain identifier
+__auto_type v = 0, w = 1; // KO: in list
+struct { __auto_type x; } s; // KO: not valid for struct/union
+__auto_type self = self; // KO: self-declared
+__auto_type undc = this; // KO: undeclared
+
+int i = 1;
+double f = 1.0;
+__auto_type i = 2; // KO: redecl, same type
+__auto_type f = 2.0f; // KO: redecl, diff type
+
+
+static int foo(int a, const int *ptr)
+{
+ __auto_type i = a;
+ __auto_type c = *ptr;
+
+ c += 1;
+ return i;
+}
+
+/*
+ * check-name: autotype-ko
+ * check-command: sparse -Wno-decl $file
+ *
+ * check-error-start
+autotype-ko.c:1:13: error: __auto_type without initializer
+autotype-ko.c:2:13: error: __auto_type on non-identifier
+autotype-ko.c:3:13: error: 'foo()' has __auto_type return type
+autotype-ko.c:4:13: error: __auto_type on declaration list
+autotype-ko.c:6:13: error: __auto_type on self-init var
+autotype-ko.c:2:20: error: invalid initializer
+autotype-ko.c:5:22: error: member 'x' has __auto_type
+autotype-ko.c:7:20: error: undefined identifier 'this'
+autotype-ko.c:11:13: error: symbol 'i' has multiple initializers (originally initialized at autotype-ko.c:9)
+autotype-ko.c:12:13: error: symbol 'f' has multiple initializers (originally initialized at autotype-ko.c:10)
+autotype-ko.c:12:13: error: symbol 'f' redeclared with different type (different type sizes):
+autotype-ko.c:12:13: float [addressable] [toplevel] f
+autotype-ko.c:10:8: note: previously declared as:
+autotype-ko.c:10:8: double [addressable] [toplevel] f
+autotype-ko.c:20:9: error: assignment to const expression
+ * check-error-end
+ */
diff --git a/validation/autotype.c b/validation/autotype.c
new file mode 100644
index 00000000..98683c93
--- /dev/null
+++ b/validation/autotype.c
@@ -0,0 +1,55 @@
+#ifdef __CHECKER__
+#define is_type(X, T) _Static_assert([typeof(X)] == [T], "")
+#else
+#define is_type(X, T) _Static_assert(1, "")
+#endif
+
+struct s {
+ int x;
+ int bf:3;
+};
+
+extern char ch;
+extern const int ci;
+
+__auto_type i = 0; is_type(i, int);
+__auto_type m = 1UL; is_type(m, unsigned long);
+__auto_type l = (int)0L; is_type(l, int);
+__auto_type c = (char)'\n'; is_type(c, char);
+__auto_type p = &i; is_type(p, int *);
+__auto_type f = 0.0; is_type(f, double);
+__auto_type s = (struct s){0}; is_type(s, struct s);
+__auto_type pci = &ci; is_type(pci, const int *);
+
+// ~~: not valid for bitfield
+__auto_type b = (struct s){0}.bf; is_type(b, int);
+
+static __auto_type si = 0; is_type(si, int);
+const __auto_type ci = 0; is_type(ci, const int);
+__auto_type ch = (char) '\n'; is_type(ch, char);
+
+static int foo(int a)
+{
+ __auto_type i = a; is_type(i, int);
+ __auto_type c = ch; is_type(c, char);
+ __auto_type ct = ci; is_type(&ct, const int *);
+
+ return ct += i + c;
+}
+
+
+
+#define __as __attribute__((address_space(42)))
+extern int __as aa;
+
+__auto_type pa = &aa; is_type(pa, int __as *);
+
+/*
+ * check-name: autotype
+ * check-command: sparse -Wno-decl $file
+ *
+ * check-error-start
+autotype.c:25:13: warning: __auto_type on bitfield
+autotype.c:37:16: error: assignment to const expression
+ * check-error-end
+ */