[Bug c/94382] New: conflicting function types should show more context

2020-03-28 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94382

Bug ID: 94382
   Summary: conflicting function types should show more context
   Product: gcc
   Version: 9.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthew at wil dot cx
  Target Milestone: ---

The diagnostic would be better if it showed the entire function prototype:

../fs/iomap/apply.c:13:1: error: conflicting types for ‘__iomap_apply’
   13 | __iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned
flags,
  | ^
In file included from ../fs/iomap/apply.c:9:
../include/linux/iomap.h:152:1: note: previous declaration of ‘__iomap_apply’
was here
  152 | __iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned
flags,
  | ^

$ grep -A3 __iomap_apply include/linux/iomap.h fs/iomap/apply.c 
include/linux/iomap.h:__iomap_apply(struct inode *inode, loff_t pos, loff_t
length, unsigned flags,
include/linux/iomap.h-  const struct iomap_ops *ops, iomap_actor_t
actor,
include/linux/iomap.h-  struct iomap *iomap, struct iomap *srcmap);
include/linux/iomap.h-
--
include/linux/iomap.h:  length = __iomap_apply(inode, pos, length, flags, ops,
actor,
include/linux/iomap.h-  &iomap, &srcmap);
include/linux/iomap.h-  /*
include/linux/iomap.h-   * Now that we have guaranteed that the space
allocation will succeed,
--
fs/iomap/apply.c:__iomap_apply(struct inode *inode, loff_t pos, loff_t length,
unsigned flags,
fs/iomap/apply.c-   struct iomap *iomap, struct iomap *srcmap,
fs/iomap/apply.c-   const struct iomap_ops *ops, iomap_actor_t
actor)
fs/iomap/apply.c-{

The bug in my code is fairly obvious, but the diagnostic doesn't show the part
of the function signature that doesn't match.

[Bug middle-end/32911] Function __attribute__ ((idempotent))

2020-08-06 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=32911

Matthew Wilcox  changed:

   What|Removed |Added

 CC||matthew at wil dot cx

--- Comment #6 from Matthew Wilcox  ---
I actually have a use for a real idempotent function, that is f(f(x)) == f(x).
I think it's different from the behaviour wanted here which is more of an
initialiser functionality.

The concrete example is Linux's compound_head() macro which takes a pointer to
a struct page and returns a pointer to a (potentially different) struct page. 
A page is its own head, and calls to compound_head can be buried inside macros.

So I'd like gcc to know that given this program:

struct page *compound_head(struct page *) __attribute__((idempotent));

int g(struct page *page)
{
struct page *head = compound_head(page);
return page->refcount;
}

int f(struct page *page)
{
struct page *head = compound_head(page);
return g(head);
}

if it inlines g() into f(), it only needs to make one call to compound_head().

[Bug middle-end/88518] New: Function call defeats -Wuninitialized

2018-12-15 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88518

Bug ID: 88518
   Summary: Function call defeats -Wuninitialized
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: middle-end
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthew at wil dot cx
  Target Milestone: ---

void g(unsigned long *);
void h(void);

void f(void)
{
unsigned long i;

h();
i++;
g(&i);
}

$ gcc -Wall -O2 -c test5.c -o /dev/null

reports no warning.  If the order of 'i++' and 'h()' are reversed, GCC emits a
warning as expected.

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 8.2.0-9'
--with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs
--enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr
--with-gcc-major-version-only --program-suffix=-8
--program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object
--disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie
--with-system-zlib --with-target-system-zlib --enable-objc-gc=auto
--enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64
--with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic
--enable-offload-targets=nvptx-none --without-cuda-driver
--enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu
--target=x86_64-linux-gnu
Thread model: posix
gcc version 8.2.0 (Debian 8.2.0-9)

[Bug middle-end/88518] Function call defeats -Wuninitialized

2018-12-16 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88518

--- Comment #2 from Matthew Wilcox  ---
Thanks!  What I actually want to do is annotate g() to the effect that it reads
the pointed-to variable before it writes it.  IOW, I want to write something
like:

void g(unsigned long __attribute__((read_before_write)) *p);
void h(void);

void f(void)
{
unsigned long i;

h();
g(&i);
}

and have gcc emit a warning that i is used uninitialised.  I tried adding i = i
prior to the call of g() through macro trickery, but was surprised that it
didn't trigger, and simplified down to this test-case.

Any chance I could get that attribute or something like it?

[Bug tree-optimization/83377] New: Missed optimization (x86): Bit operations should be converted to arithmetic

2017-12-11 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83377

Bug ID: 83377
   Summary: Missed optimization (x86): Bit operations should be
converted to arithmetic
   Product: gcc
   Version: 7.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthew at wil dot cx
  Target Milestone: ---

GCC fails to optimise

if (x & 2) y = (x &~ 2)

into

if (x & 2) y = (x - 2)

in cases where that would be advantageous.

Here's one example, which I'm sure will upset the C pedants, but is relatively
common in codebases which use typed pointers based on the lower bits.

int a(void *);
struct s { struct s *s; };
int b(void *x) {
void *p = x;
if ((unsigned long)x & 2)
p = ((struct s *)((unsigned long)x & ~2UL))->s;
return a(p);
}
int c(void *x) {
void *p = x;
if ((unsigned long)x & 2)
p = ((struct s *)((unsigned long)x - 2))->s;
return a(p);
}

On x86, the difference between the assembly output is clear; function c is
smaller than function b:

 :
   0:   40 f6 c7 02 test   $0x2,%dil
   4:   74 07   je d 
   6:   48 83 e7 fd and$0xfffd,%rdi
   a:   48 8b 3fmov(%rdi),%rdi
   d:   e9 00 00 00 00  jmpq   12 
  12:   0f 1f 40 00 nopl   0x0(%rax)
  16:   66 2e 0f 1f 84 00 00nopw   %cs:0x0(%rax,%rax,1)
  1d:   00 00 00 

0020 :
  20:   40 f6 c7 02 test   $0x2,%dil
  24:   74 04   je 2a 
  26:   48 8b 7f fe mov-0x2(%rdi),%rdi
  2a:   e9 00 00 00 00  jmpq   2f 

This is true with both -O3 and -O2.  I have other functions where the savings
are greater (two insns and seven bytes), but the root cause is the same; a
failure to optimise an AND into a SUB (which can then be fused with a load)

I'm filing this one under tree-optimisation rather than RTL, because I think
it's a common feature in CPUs to have load (reg + offset), and relatively
uncommon (in fact I don't know of one) to have load (reg & mask).  I'm sure
some CPUs don't even have (reg + offset) addressing modes, but they wouldn't be
harmed by such an optimisation.

[Bug c/83653] New: GCC fails to remove a can't-happen call on ia64

2018-01-02 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83653

Bug ID: 83653
   Summary: GCC fails to remove a can't-happen call on ia64
   Product: gcc
   Version: 6.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthew at wil dot cx
  Target Milestone: ---

Created attachment 43009
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43009&action=edit
Gzipped preprocessed source

This is an excerpt from the Linux kernel, with some patches that I'm preparing
to go in.  The 0day build-bot reports a problem with an undefined
__bad_increment_for_ia64_fetch_and_add.

I can reproduce the problem by taking the attached preprocessed source and
compiling it with gcc -O2 -o shmem.o -c shmem.i and then running nm shmem.o
|grep __bad

Manually inlining page_ref_sub() in the included test-case makes the problem go
away, as does simply deleting the call to page_ref_sub() (at line 50756).

Command line:   gcc -Wp,-MD,mm/.shmem.o.d  -nostdinc -isystem
/usr/lib/gcc/ia64-linux-gnu/4.6/include -I./arch/ia64/include
-I./arch/ia64/include/generated  -I./include -I./arch/ia64/include/uapi
-I./arch/ia64/include/generated/uapi -I./include/uapi
-I./include/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__
-DHAVE_WORKING_TEXT_ALIGN -DHAVE_MODEL_SMALL_ATTRIBUTE
-DHAVE_SERIALIZE_DIRECTIVE -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs
-fno-strict-aliasing -fno-common -fshort-wchar
-Werror-implicit-function-declaration -Wno-format-security -std=gnu89
-Wno-unused-but-set-variable -fno-PIE -pipe -ffixed-r13
-mfixed-range=f12-f15,f32-f127 -falign-functions=32 -frename-registers
-fno-optimize-sibling-calls -fno-delete-null-pointer-checks -O2
-DCC_HAVE_ASM_GOTO -Wframe-larger-than=2048 -fno-stack-protector
-fomit-frame-pointer -fno-var-tracking-assignments -g
-Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow
-fno-stack-check -fconserve-stack -Werror=implicit-int
-Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types
-Werror=designated-init  -mconstant-gp  -DKBUILD_BASENAME='"shmem"' 
-DKBUILD_MODNAME='"shmem"' -c -o mm/.tmp_shmem.o mm/shmem.c

[Bug middle-end/83653] [6 Regression] GCC fails to remove a can't-happen call on ia64

2018-01-08 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83653

--- Comment #2 from Matthew Wilcox  ---
7.2, 6.2, 5.5 and 4.9 fail.  4.6.3 succeeds.

[Bug middle-end/83653] [6/7/8 Regression] GCC fails to remove a can't-happen call on ia64

2018-01-10 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83653

--- Comment #5 from Matthew Wilcox  ---
Hi Aldy!

Thanks for looking into this.  Yes, I agree, there's no way that GCC can know
this is a constant, but that *should* have been taken care of.  Please pardon
me copying and pasting from the original source file rather than the
preprocessed source, but I find it utterly impossible to work with the
preprocessed source ...

#define atomic_sub_return(i,v)  \
({  \
int __ia64_asr_i = (i); \
(__builtin_constant_p(i)\
 && (   (__ia64_asr_i ==   1) || (__ia64_asr_i ==   4)  \
 || (__ia64_asr_i ==   8) || (__ia64_asr_i ==  16)  \
 || (__ia64_asr_i ==  -1) || (__ia64_asr_i ==  -4)  \
 || (__ia64_asr_i ==  -8) || (__ia64_asr_i == -16)))\
? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter)  \
: ia64_atomic_sub(__ia64_asr_i, v); \
})

That __builtin_constant_p() *should* have led GCC to throw up its hands, not
bother checking for the +/- 1, 4, 8, 16 cases and just call ia64_atomic_sub(). 
Looking at the disassembly, I see a BBB bundle, indicating quite strongly to me
that it is testing for all of these cases, and the __builtin_constant_p is
being ... ignored?  misunderstood?

Thanks!

[Bug middle-end/83653] [6/7/8 Regression] GCC fails to remove a can't-happen call on ia64

2018-01-11 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83653

--- Comment #7 from Matthew Wilcox  ---
OK, so how should we write this function/macro to accomplish what we want?

And the requirement is "If the argument is one of these eight special
constants, use this special instruction, otherwise call this function".  Even
if the argument happens to be one of the eight special values at runtime, we
should still call the function, because it's not worth doing runtime checks; we
only want a compile-time optimisation.  And it's worth the compile-time
optimisation because adding constant 1/-1 is really, really common.

[Bug middle-end/83653] [6/7/8 Regression] GCC fails to remove a can't-happen call on ia64

2018-01-11 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83653

--- Comment #9 from Matthew Wilcox  ---
Maybe I'm a little slow, but I don't see what the path is that sets 'nr' to 0. 
It's 1UL << compound_order.  Typically, compound_order is 0, although it may be
anything up to log2(number of pages in the machine).  Are you saying that nr
could be 0 because DOM2 thinks compound_order() could be larger than 64, and
thus undefined?

[Bug middle-end/83653] [6/7/8 Regression] GCC fails to remove a can't-happen call on ia64

2018-01-11 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83653

--- Comment #11 from Matthew Wilcox  ---
I'm sorry, I still don't get it.

What I think you're saying is that GCC performs this optimisation:

nr = 1UL << compound_order(page);
atomic_sub_return(x, nr);

into:

if (PageHead(page))
  atomic_sub_return(x, 1);
else
  atomic_sub_return(x, 1UL << page[1].order)

That seems like a great optimisation to me, and I'm all for it.  What I don't
understand is where the b_c_p call gets lost.

Also, this bug is pretty fragile.  If I replace the 'nr' in the call to
atomic_sub_return with '1UL << compound_order(page)', the bug goes away.

Anyway, I have no vested interest in ia64 or the code that's currently using
__b_c_p.  I just want it to stop blocking me getting my patch in.  It's a bit
different from 72785 because I can't just resolve it by removing the checking
code.  Just tell me what the macro should look like.

[Bug middle-end/83653] [6/7/8 Regression] GCC fails to remove a can't-happen call on ia64

2018-01-11 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83653

--- Comment #14 from Matthew Wilcox  ---
Confirmed this fixes the problem.  I'll send it to Tony and see if he likes it.
 May I add your Signed-off-by to the patch?

[Bug c/85053] New: free not listed as built-in

2018-03-23 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85053

Bug ID: 85053
   Summary: free not listed as built-in
   Product: gcc
   Version: 8.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthew at wil dot cx
  Target Milestone: ---

The function free() is not listed as a built-in in the manual, but the source
code has several references to BUILT_IN_FREE.  I believe the manual should be
adjusted as so:

-@code{fprintf}, @code{fputs}, @code{frexp}, @code{fscanf},
+@code{fprintf}, @code{fputs}, @code{free}, @code{frexp}, @code{fscanf},

(not submitting this as a real patch because I don't have a copyright
assignment on file.  this patch shouldn't need one!)

[Bug c/85055] New: warn on accessing free memory

2018-03-23 Thread matthew at wil dot cx
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85055

Bug ID: 85055
   Summary: warn on accessing free memory
   Product: gcc
   Version: 7.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthew at wil dot cx
  Target Milestone: ---

GCC knows that a pointer passed to free() is no longer valid, but it misses an
opportunity to warn here:

char f(char *foo)
{
free(foo);
return foo[0];
}

[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; }

[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/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)