diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-11-03 21:49:15 +0100 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-03-24 10:51:35 +0100 |
| commit | 79f7ac984473d031dfb9cef00119c2d542d0d4a6 (patch) | |
| tree | 5af6e6713ee40d83b572e96897b644e1938b4c5e /validation | |
| parent | bff9b106e8fc02ab89da5fc7bf6d5e05b676da13 (diff) | |
| download | sparse-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.c | 45 | ||||
| -rw-r--r-- | validation/autotype.c | 55 |
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 + */ |
