[Bug c/101645] warn about neg of unsigned type should be added to -Wsign-conversion

2021-07-28 Thread matthew at wil dot cx via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101645

--- Comment #4 from Matthew Wilcox  ---
On second thoughts -Wsign-conversion is useless.  Consider that it warns on
this:

unsigned long f(unsigned long x, int y) {
return x + y;
}

Both gcc and clang emit a warning, which makes it useless.  That code obviously
does what the programmer intended.

What would be useful is a warning which diagnoses code which behaves
differently in infinite-precision arithmetic vs the C promotion rules.

For example,

unsigned long g(unsigned char v, int s) {
return v << s;
}

By the C standard, v is promoted to int, shifted by s and then promoted to
unsigned long.  This is a fertile source of bugs as it's easy to overlook that
v will not be promoted to unsigned long first.

(by the way, this is another example where clang diagnoses with -Wsign-compare
and gcc doesn't.)

Another example plucked from real life:

long long h(unsigned int x) {
return x * 4096;
}

(slightly changed to demonstrate the problem on LP64; the original was from
unsigned long to long long, and it is only a bug on ILP32)

[Bug c/101645] New: -Wsign-conversion misses negation of unsigned int

2021-07-27 Thread matthew at wil dot cx via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101645

Bug ID: 101645
   Summary: -Wsign-conversion misses negation of unsigned int
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthew at wil dot cx
  Target Milestone: ---

Test case:

unsigned long a(void);
void b(long);
void c(void) {
unsigned int x = a();
b(-x);
}

There is a missed warning in the call to b().  x is negated, but as an int.  It
is then passed to b() which sees a very large positive number instead of a
small negative number.  This has recently affected the Linux codebase, and it's
disappointing that gcc doesn't have a warning that we could enable to find it.

https://godbolt.org/z/xvaxh1rqr

shows that Clang does spot this with -Wsign-conversion, but GCC currently
doesn't (it only warns for line 4 and not line 5).  Admittedly the Clang
diagnostic message isn't the greatest, but at least it says _something_.

[Bug c/99997] Missed optimisation with -Os

2021-04-09 Thread matthew at wil dot cx via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=7

Matthew Wilcox  changed:

   What|Removed |Added

 CC||matthew at wil dot cx

--- Comment #1 from Matthew Wilcox  ---
Actually, it should eliminate the one _after_ the L2 label.  It just moved the
constant 1 into %eax and doesn't need to limit it again.

[Bug c/97287] New: Warn for expanding range of an arithmetic type

2020-10-04 Thread matthew at wil dot cx via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97287

Bug ID: 97287
   Summary: Warn for expanding range of an arithmetic type
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthew at wil dot cx
  Target Milestone: ---

I've just fixed multiple instances of bugs that look a lot like function f()
when they should have been function g().  This affects filesystems in Linux
which have to remember to cast an unsigned long to an off_t before shifting (or
there will be a bug on 32-bit kernels when dealing with files that are larger
than 4GB).

When I looked for a warning option to add, I thought -Warith-conversions might
do the job, but it doesn't.  Maybe this functionality should be added there, or
maybe it should have its own warning.

I think what we're looking for is an operation which expands the range of the
type (left shift, multiplication, addition; maybe subtraction?) and the rules
of C require the operation to be done in a narrower type, but the result is
assigned to a wider type.

unsigned long long f(unsigned int i) { return i * 4096; }
unsigned long long g(unsigned int i) { return i * 4096ULL; }