summaryrefslogtreecommitdiff
path: root/sys/src/cmd/cc
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2018-11-18 20:42:45 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2018-11-18 20:42:45 +0100
commit485a3301e6119f0c85d7869d469fc0a0888e49c1 (patch)
tree7e79e11abf1349597d3226f8cef5a4493c413bf1 /sys/src/cmd/cc
parentb6251bff913972b5dfb421813fe97a5bfff3627f (diff)
cc: fix wrong "useless or misleading comparison" warning
to reproduce: u8int x, y; x = 0xff; y = 0xc0; if((s8int)(x & y) >= 0) print("help\n"); compiles correctly but prints a warning warning: test.c:11 useless or misleading comparison: UINT >= 0 the issue is that compar() unconditionally skipped over all left casts ignoring the case when a cast would sign extend the value. the new code only skips over the cast when the original type with is smaller than the cast result or when they are equal width and types have same signedness. so the effective left hand side type is the last truncation or sign extension.
Diffstat (limited to 'sys/src/cmd/cc')
-rw-r--r--sys/src/cmd/cc/com.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/sys/src/cmd/cc/com.c b/sys/src/cmd/cc/com.c
index b8a3b5c44..f67294510 100644
--- a/sys/src/cmd/cc/com.c
+++ b/sys/src/cmd/cc/com.c
@@ -1373,14 +1373,21 @@ compar(Node *n, int reverse)
/*
* Skip over left casts to find out the original expression range.
*/
- while(l->op == OCAST)
+ while(l->op == OCAST){
+ lt = l->type;
+ rt = l->left->type;
+ if(lt == T || rt == T)
+ return 0;
+ if(lt->width < rt->width)
+ break;
+ if(lt->width == rt->width && ((lt->etype ^ rt->etype) & 1) != 0)
+ break;
l = l->left;
+ }
if(l->op == OCONST)
return 0;
lt = l->type;
- if(lt == T)
- return 0;
- if(lt->etype == TXXX || lt->etype > TUVLONG)
+ if(lt == T || lt->etype == TXXX || lt->etype > TUVLONG)
return 0;
/*
@@ -1399,16 +1406,17 @@ compar(Node *n, int reverse)
if((rt->etype&1) && r->vconst < 0) /* signed negative */
x.a = ~0ULL;
- if((lt->etype&1)==0){
+ if(lt->etype & 1){
+ /* signed */
+ lo = big(~0ULL, -(1LL<<(lt->width*8-1)));
+ hi = big(0, (1LL<<(lt->width*8-1))-1);
+ } else {
/* unsigned */
lo = big(0, 0);
if(lt->width == 8)
hi = big(0, ~0ULL);
else
- hi = big(0, (1LL<<(l->type->width*8))-1);
- }else{
- lo = big(~0ULL, -(1LL<<(l->type->width*8-1)));
- hi = big(0, (1LL<<(l->type->width*8-1))-1);
+ hi = big(0, (1LL<<(lt->width*8))-1);
}
switch(op){
@@ -1462,4 +1470,3 @@ if(debug['y']) prtree(n, "strange");
warn(n, "useless or misleading comparison: %s", cmpbuf);
return 0;
}
-