* [PATCH 0/3] validate expression's type in conditionals @ 2017-01-29 11:34 Luc Van Oostenryck 2017-01-29 11:34 ` [PATCH 1/3] fix conditional context test case with void Luc Van Oostenryck ` (2 more replies) 0 siblings, 3 replies; 4+ messages in thread From: Luc Van Oostenryck @ 2017-01-29 11:34 UTC (permalink / raw) To: linux-sparse; +Cc: Josh Triplett, Luc Van Oostenryck This serie aims to detect incorrect types used in conditionals. Patch 1 fix a test case where a void was used ina conditional. Patch 2 is an helper for the next patch. Patch 3 do the validation. Luc Van Oostenryck (3): fix conditional context test case with void add helper: is_scalar_type() validate expression's type in conditionals evaluate.c | 5 +++ symbol.h | 22 ++++++++++ validation/conditional-type.c | 99 +++++++++++++++++++++++++++++++++++++++++++ validation/context.c | 2 +- 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 validation/conditional-type.c -- 2.11.0 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] fix conditional context test case with void 2017-01-29 11:34 [PATCH 0/3] validate expression's type in conditionals Luc Van Oostenryck @ 2017-01-29 11:34 ` Luc Van Oostenryck 2017-01-29 11:34 ` [PATCH 2/3] add helper: is_scalar_type() Luc Van Oostenryck 2017-01-29 11:34 ` [PATCH 3/3] validate expression's type in conditionals Luc Van Oostenryck 2 siblings, 0 replies; 4+ messages in thread From: Luc Van Oostenryck @ 2017-01-29 11:34 UTC (permalink / raw) To: linux-sparse; +Cc: Josh Triplett, Luc Van Oostenryck The test file for context checking contains a few test cases with a conditional, mimicking kernels's __cond_lock(). But the macro involved use as condition the return value of a function, _ca(), which itself returns void ... Fix the test by giving _ca() a return type of 'int'. CC: Josh Triplett <josh@joshtriplett.org> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- validation/context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validation/context.c b/validation/context.c index 33b70b84b..b9500dc75 100644 --- a/validation/context.c +++ b/validation/context.c @@ -10,7 +10,7 @@ static void r(void) __attribute__((context(1,0))) __context__(-1); } -extern void _ca(int fail); +extern int _ca(int fail); #define ca(fail) __cond_lock(_ca(fail)) static void good_paired1(void) -- 2.11.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] add helper: is_scalar_type() 2017-01-29 11:34 [PATCH 0/3] validate expression's type in conditionals Luc Van Oostenryck 2017-01-29 11:34 ` [PATCH 1/3] fix conditional context test case with void Luc Van Oostenryck @ 2017-01-29 11:34 ` Luc Van Oostenryck 2017-01-29 11:34 ` [PATCH 3/3] validate expression's type in conditionals Luc Van Oostenryck 2 siblings, 0 replies; 4+ messages in thread From: Luc Van Oostenryck @ 2017-01-29 11:34 UTC (permalink / raw) To: linux-sparse; +Cc: Josh Triplett, Luc Van Oostenryck Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- symbol.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/symbol.h b/symbol.h index 9b3f1604e..b0176bc5e 100644 --- a/symbol.h +++ b/symbol.h @@ -372,6 +372,28 @@ static inline int is_bool_type(struct symbol *type) return type == &bool_ctype; } +static inline int is_scalar_type(struct symbol *type) +{ + if (type->type == SYM_NODE) + type = type->ctype.base_type; + switch (type->type) { + case SYM_ENUM: + case SYM_BITFIELD: + case SYM_PTR: + case SYM_ARRAY: // OK, will be a PTR after conversion + case SYM_FN: + case SYM_RESTRICT: // OK, always integer types + return 1; + default: + break; + } + if (type->ctype.base_type == &int_type) + return 1; + if (type->ctype.base_type == &fp_type) + return 1; + return 0; +} + static inline int is_function(struct symbol *type) { return type && type->type == SYM_FN; -- 2.11.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] validate expression's type in conditionals 2017-01-29 11:34 [PATCH 0/3] validate expression's type in conditionals Luc Van Oostenryck 2017-01-29 11:34 ` [PATCH 1/3] fix conditional context test case with void Luc Van Oostenryck 2017-01-29 11:34 ` [PATCH 2/3] add helper: is_scalar_type() Luc Van Oostenryck @ 2017-01-29 11:34 ` Luc Van Oostenryck 2 siblings, 0 replies; 4+ messages in thread From: Luc Van Oostenryck @ 2017-01-29 11:34 UTC (permalink / raw) To: linux-sparse; +Cc: Josh Triplett, Luc Van Oostenryck This wasn't done yet, in particular void values was accepted inside if statements, which lead to strange situations after linearization. Implement this simply by calling the newly created is_scalar_type() in evaluate_conditional() and issuing an appropriate diagnostic when the check fail. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- evaluate.c | 5 +++ validation/conditional-type.c | 99 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 validation/conditional-type.c diff --git a/evaluate.c b/evaluate.c index e350c0c08..f3616e450 100644 --- a/evaluate.c +++ b/evaluate.c @@ -865,6 +865,11 @@ static struct symbol *evaluate_conditional(struct expression *expr, int iterator if (ctype) { if (is_safe_type(ctype)) warning(expr->pos, "testing a 'safe expression'"); + if (!is_scalar_type(ctype)) { + sparse_error(expr->pos, "incorrect type in conditional"); + info(expr->pos, " got %s", show_typename(ctype)); + ctype = NULL; + } } return ctype; diff --git a/validation/conditional-type.c b/validation/conditional-type.c new file mode 100644 index 000000000..a14c05ec1 --- /dev/null +++ b/validation/conditional-type.c @@ -0,0 +1,99 @@ +extern void afun(void); +extern void vcond(void); +static int array[3]; + +struct state { + int nr:2; +}; + +enum number { + zero, + one, + two, + many, +}; + +static int bad_if(struct state s) +{ + if (vcond()) return 1; + if (s) return 1; + return 0; +} +static void bad_if2(int *a, int *b) +{ + if (vcond()) *a = 1; + *b = 0; +} +static int bad_sel(struct state s) +{ + return vcond() ? 1 : 0; + return s ? 1 : 0; +} +static int bad_loop_void(void) +{ + while (vcond()) + ; + for (;vcond();) + ; + do + ; + while (vcond()); + return 0; +} + + +static int good_if_int(int a, _Bool b, long c, unsigned char d) +{ + if (a) return 1; + if (b) return 1; + if (c) return 1; + if (d) return 1; + return 0; +} +static int good_if_float(float a, double b) +{ + if (a) return 1; + if (b) return 1; + return 0; +} +static int good_if_enum(void) +{ + if (many) return 1; + return 0; +} +static int good_if_bitfield(struct state s, struct state *p) +{ + if (s.nr) return 1; + if (p->nr) return 1; + return 0; +} +static int good_if_ptr(void *ptr) +{ + if (ptr) return 1; + if (array) return 1; + if (afun) return 1; + return 0; +} + +/* + * check-name: conditional-type + * + * check-error-start +conditional-type.c:18:18: error: incorrect type in conditional +conditional-type.c:18:18: got void +conditional-type.c:19:13: error: incorrect type in conditional +conditional-type.c:19:13: got struct state s +conditional-type.c:24:18: error: incorrect type in conditional +conditional-type.c:24:18: got void +conditional-type.c:29:21: error: incorrect type in conditional +conditional-type.c:29:21: got void +conditional-type.c:30:16: error: incorrect type in conditional +conditional-type.c:30:16: got struct state s +conditional-type.c:34:21: error: incorrect type in conditional +conditional-type.c:34:21: got void +conditional-type.c:36:20: error: incorrect type in conditional +conditional-type.c:36:20: got void +conditional-type.c:40:21: error: incorrect type in conditional +conditional-type.c:40:21: got void + * check-error-end + */ -- 2.11.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-01-29 15:12 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-01-29 11:34 [PATCH 0/3] validate expression's type in conditionals Luc Van Oostenryck 2017-01-29 11:34 ` [PATCH 1/3] fix conditional context test case with void Luc Van Oostenryck 2017-01-29 11:34 ` [PATCH 2/3] add helper: is_scalar_type() Luc Van Oostenryck 2017-01-29 11:34 ` [PATCH 3/3] validate expression's type in conditionals Luc Van Oostenryck
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).