As an extension, allow conditional expressions (?:) with one side of type 'void' and consider the result to also be void. The warning can be reinstated with the flag '-Wcond-void'. Note: I only see a single occurrence of this in the kernel. Suggested-by: Randy Dunlap <rdunlap@xxxxxxxxxxxxx> Suggested-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- evaluate.c | 7 +++++++ lib.c | 2 ++ lib.h | 1 + sparse.1 | 7 +++++++ validation/cond-err-expand.c | 2 +- 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/evaluate.c b/evaluate.c index 919c944cf..fb1a0548d 100644 --- a/evaluate.c +++ b/evaluate.c @@ -1205,6 +1205,13 @@ static struct symbol *evaluate_conditional_expression(struct expression *expr) goto out; } + // extension: allow the result be void is one side is void + if (ltype == &void_ctype || rtype == &void_ctype) { + ctype = &void_ctype; + if (!Wcond_void) + goto out; + } + if ((lclass | rclass) & TYPE_PTR) { int is_null1 = is_null_pointer_constant(*cond); int is_null2 = is_null_pointer_constant(expr->cond_false); diff --git a/lib.c b/lib.c index 83e6a1e1b..c16d87778 100644 --- a/lib.c +++ b/lib.c @@ -257,6 +257,7 @@ int Wbitwise_pointer = 0; int Wcast_from_as = 0; int Wcast_to_as = 0; int Wcast_truncate = 1; +int Wcond_void = 0; int Wconstant_suffix = 0; int Wconstexpr_not_const = 0; int Wcontext = 1; @@ -639,6 +640,7 @@ static const struct flag warnings[] = { { "cast-from-as", &Wcast_from_as }, { "cast-to-as", &Wcast_to_as }, { "cast-truncate", &Wcast_truncate }, + { "cond-void", &Wcond_void }, { "constant-suffix", &Wconstant_suffix }, { "constexpr-not-const", &Wconstexpr_not_const}, { "context", &Wcontext }, diff --git a/lib.h b/lib.h index 697c977a1..2549c8872 100644 --- a/lib.h +++ b/lib.h @@ -145,6 +145,7 @@ extern int Wbitwise_pointer; extern int Wcast_from_as; extern int Wcast_to_as; extern int Wcast_truncate; +extern int Wcond_void; extern int Wconstant_suffix; extern int Wconstexpr_not_const; extern int Wcontext; diff --git a/sparse.1 b/sparse.1 index beb484423..71ac0c646 100644 --- a/sparse.1 +++ b/sparse.1 @@ -117,6 +117,13 @@ Sparse issues these warnings by default. To turn them off, use \fB\-Wno\-cast\-truncate\fR. . .TP +.B \-Wconditional\-void +Warn if one side of a conditional expression (\fB? :\fR) is of type +void and the other one not. +As an extension, Sparse consider the result of such expressions as also +having the type void. +. +.TP .B \-Wconstant\-suffix Warn if an integer constant is larger than the maximum representable value of the type indicated by its type suffix (if any). For example, on a diff --git a/validation/cond-err-expand.c b/validation/cond-err-expand.c index b52624bc9..714cb23eb 100644 --- a/validation/cond-err-expand.c +++ b/validation/cond-err-expand.c @@ -15,7 +15,7 @@ void bar(void) /* * check-name: cond-err-expand.c - * check-command: test-linearize -Wno-decl $file + * check-command: test-linearize -Wcond-void -Wno-decl $file * * check-error-start cond-err-expand.c:8:11: error: incompatible types in conditional expression (different base types): -- 2.23.0