aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2009-02-27 09:34:48 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2013-02-12 09:23:26 -0500
commitf18347c900f89ee3a7d146116482d70f82cee936 (patch)
tree65005bb5d758ea067f5a44d4b9ee6e78b4e275ea
parent519a65d26c4c1a9a72046ab4dcb594a64d19a662 (diff)
downloadsparse-f18347c900f89ee3a7d146116482d70f82cee936.tar.gz
Gentler handling of bitwise warnings in unary operations
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--evaluate.c26
-rw-r--r--validation/foul-bitwise.c6
2 files changed, 21 insertions, 11 deletions
diff --git a/evaluate.c b/evaluate.c
index bebe9687..29e094e7 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1696,16 +1696,20 @@ static struct symbol *evaluate_postop(struct expression *expr)
{
struct expression *op = expr->unop;
struct symbol *ctype = op->ctype;
- int class = classify_type(op->ctype, &ctype);
+ int class = classify_type(ctype, &ctype);
int multiply = 0;
+ if (!class || class & TYPE_COMPOUND) {
+ expression_error(expr, "need scalar for ++/--");
+ return NULL;
+ }
if (!lvalue_expression(expr->unop)) {
expression_error(expr, "need lvalue expression for ++/--");
return NULL;
}
if ((class & TYPE_RESTRICT) && restricted_unop(expr->op, &ctype))
- return bad_expr_type(expr);
+ unrestrict(expr, class, &ctype);
if (class & TYPE_NUM) {
multiply = 1;
@@ -1735,13 +1739,13 @@ static struct symbol *evaluate_sign(struct expression *expr)
/* should be an arithmetic type */
if (!(class & TYPE_NUM))
return bad_expr_type(expr);
- if (!(class & (TYPE_FLOAT|TYPE_RESTRICT))) {
- struct symbol *rtype = integer_promotion(ctype);
- expr->unop = cast_to(expr->unop, rtype);
- ctype = rtype;
- } else if ((class & TYPE_FLOAT) && expr->op != '~') {
- /* no conversions needed */
- } else if ((class & TYPE_RESTRICT) && !restricted_unop(expr->op, &ctype)) {
+ if (class & TYPE_RESTRICT)
+ goto Restr;
+Normal:
+ if (!(class & TYPE_FLOAT)) {
+ ctype = integer_promotion(ctype);
+ expr->unop = cast_to(expr->unop, ctype);
+ } else if (expr->op != '~') {
/* no conversions needed */
} else {
return bad_expr_type(expr);
@@ -1750,6 +1754,10 @@ static struct symbol *evaluate_sign(struct expression *expr)
*expr = *expr->unop;
expr->ctype = ctype;
return ctype;
+Restr:
+ if (restricted_unop(expr->op, &ctype))
+ unrestrict(expr, class, &ctype);
+ goto Normal;
}
static struct symbol *evaluate_preop(struct expression *expr)
diff --git a/validation/foul-bitwise.c b/validation/foul-bitwise.c
index 9e21eab7..4b542cf9 100644
--- a/validation/foul-bitwise.c
+++ b/validation/foul-bitwise.c
@@ -24,7 +24,9 @@ static __le16 bar(__le16 a)
* check-error-start
foul-bitwise.c:9:16: warning: restricted __le16 degrades to integer
foul-bitwise.c:9:22: warning: restricted __le16 degrades to integer
-foul-bitwise.c:19:16: error: incompatible types for operation (-)
-foul-bitwise.c:19:16: argument has type restricted __le16 [usertype] a
+foul-bitwise.c:19:16: warning: restricted __le16 degrades to integer
+foul-bitwise.c:19:16: warning: incorrect type in return expression (different base types)
+foul-bitwise.c:19:16: expected restricted __le16
+foul-bitwise.c:19:16: got int
* check-error-end
*/