Created attachment 45127 [details] creduce code There seems to be a regression in 8.2.0 from the previous release. See original post at: * https://lkml.org/lkml/2018/8/16/117 Reduced test case: $ cat bug.c typedef struct { int a[4] } b, c; d, e; inline f(void *g, int h, int p3) { unsigned *i = 0; int copy = ({ d ?: p3; }); g += *i - h; memcpy(e, g, copy); *i = copy; } j() { f(j, 0, sizeof(c)); union { b k } vrsave; f(&vrsave, 33 * sizeof(c), 1); } With: $ powerpc-linux-gnu-gcc -Warray-bounds -mcpu=powerpc -fno-delete-null-pointer-checks -O2 -c bug.c ... bug.c:9:3: warning: 'memcpy' offset [-527, -529] is out of the bounds [0, 16] of object 'vrsave' with type 'union <anonymous>' [-Warray-bounds] memcpy(e, g, copy); For reference: $ powerpc-linux-gnu-gcc --version powerpc-linux-gnu-gcc (Debian 8.2.0-9) 8.2.0
I think the creduced testcase is bogus and undefined behavior happens. There is derefering of a NULL pointer there.
Yes you have -fno-delete-null-pointer-checks but that just will not cause an trap to happen. Can you attach the original preprocessed source because that will help to decide if this is a valid warning or not?
Based on the text of the warning this looks similar to pr86827 except that I don't see it with the powerpc64-linux or x86_64-linux compilers and I don't have a powerpc cross-compiler handy at the moment. I do see several other warnings for the test case. Not sure if they have any bearing on the reported problem but they do imply the test case is invalid (valid test cases are preferable when reporting problems other than ICE). pr88273.c:3:1: warning: no semicolon at end of struct or union 3 | } b, c; | ^ pr88273.c:4:1: warning: data definition has no type or storage class 4 | d, e; | ^ pr88273.c:4:1: warning: type defaults to ‘int’ in declaration of ‘d’ [-Wimplicit-int] pr88273.c:4:4: warning: type defaults to ‘int’ in declaration of ‘e’ [-Wimplicit-int] 4 | d, e; | ^ pr88273.c:5:8: warning: return type defaults to ‘int’ [-Wimplicit-int] 5 | inline f(void *g, int h, int p3) { | ^ pr88273.c: In function ‘f’: pr88273.c:9:20: warning: passing argument 1 of ‘__builtin_memcpy’ makes pointer from integer without a cast [-Wint-conversion] 9 | __builtin_memcpy(e, g, copy); | ^ | | | int pr88273.c:9:20: note: expected ‘void *’ but argument is of type ‘int’ pr88273.c: At top level: pr88273.c:12:1: warning: return type defaults to ‘int’ [-Wimplicit-int] 12 | j() { | ^ pr88273.c: In function ‘j’: pr88273.c:16:3: warning: no semicolon at end of struct or union 16 | } vrsave; | ^
(In reply to Martin Sebor from comment #3) > Based on the text of the warning this looks similar to pr86827 except that I > don't see it with the powerpc64-linux or x86_64-linux compilers and I don't > have a powerpc cross-compiler handy at the moment. It's there on 32-bit powerpc. % powerpc-e300c3-linux-gnu-gcc-9.0.0-alpha20181125 -Warray-bounds -mcpu=powerpc -fno-delete-null-pointer-checks -O2 -c pr88273.c pr88273.c:3:1: warning: no semicolon at end of struct or union 3 | } b, c; | ^ pr88273.c:4:1: warning: data definition has no type or storage class 4 | d, e; | ^ pr88273.c:4:1: warning: type defaults to 'int' in declaration of 'd' [-Wimplicit-int] pr88273.c:4:4: warning: type defaults to 'int' in declaration of 'e' [-Wimplicit-int] 4 | d, e; | ^ pr88273.c:5:8: warning: return type defaults to 'int' [-Wimplicit-int] 5 | inline f(void *g, int h, int p3) { | ^ pr88273.c: In function 'f': pr88273.c:9:3: warning: implicit declaration of function 'memcpy' [-Wimplicit-function-declaration] 9 | memcpy(e, g, copy); | ^~~~~~ pr88273.c:9:3: warning: incompatible implicit declaration of built-in function 'memcpy' pr88273.c:1:1: note: include '<string.h>' or provide a declaration of 'memcpy' +++ |+#include <string.h> 1 | typedef struct { pr88273.c:9:10: warning: passing argument 1 of 'memcpy' makes pointer from integer without a cast [-Wint-conversion] 9 | memcpy(e, g, copy); | ^ | | | int pr88273.c:9:10: note: expected 'void *' but argument is of type 'int' pr88273.c: At top level: pr88273.c:12:1: warning: return type defaults to 'int' [-Wimplicit-int] 12 | j() { | ^ pr88273.c: In function 'j': pr88273.c:16:3: warning: no semicolon at end of struct or union 16 | } vrsave; | ^ In function 'f', inlined from 'j' at pr88273.c:17:3: pr88273.c:9:3: warning: 'memcpy' offset [-527, -529] is out of the bounds [0, 16] of object 'vrsave' with type 'union <anonymous>' [-Warray-bounds] 9 | memcpy(e, g, copy); | ^~~~~~~~~~~~~~~~~~ pr88273.c: In function 'j': pr88273.c:16:5: note: 'vrsave' declared here 16 | } vrsave; | ^~~~~~
Created attachment 45128 [details] save-temps
The creduced file definitely does not represent at all the original file. It is the second call to user_regset_copyin which is complaining. Without looking into the gimple dump, I think there is jump threading going on which might cause this warning.
Here is the new creduced test case: $ cat bug.c #include <string.h> typedef struct { int b[4] } c; void* d; unsigned e; inline int h(void *i, int p2, int j) { if (j < 0 || e < j) { int copy = ({ typeof(e) k = j - e; k; }); i += e - p2; memcpy(d, i, copy); e = copy; } } void a() { int g = h(&g, 0, sizeof(c)); union { c f; } vrsave; h(&vrsave, 33 * sizeof(c), -1); } Compilation: $ powerpc-linux-gnu-gcc -Warray-bounds -mcpu=powerpc -O2 -c bug.c Using creduce with: #!/bin/bash powerpc-linux-gnu-gcc -Warray-bounds -mcpu=powerpc -O2 -c ptrace2.i >& output.txt grep error output.txt && exit 1 grep -F "warning: 'memcpy' offset [-527, -529] is out of the bounds [0, 16] of object 'vrsave' with type 'union <anonymous>'" output.txt >/dev/null 2>&1
For reference: $ cat ptrace2.c #include <linux/regset.h> #define CREATE_TRACE_POINTS #include <trace/events/syscalls.h> void a(int b, int c, void *d) { void *e = 0; int g = user_regset_copyout(&b, &c, d, e, g, 0, sizeof(vector128)); union { elf_vrreg_t f } vrsave; user_regset_copyout(&b, &c, d, e, &vrsave, 33 * sizeof(vector128), -1); }
Slightly cleaned up test-case: $ cat /home/marxin/Programming/testcases/pr88273-2.c typedef struct { int b[4]; } c; void* d; unsigned e; inline int h(void *i, int p2, int j) { if (j < 0 || e < j) { int copy = j - e; i += e - p2; __builtin_memcpy(d, i, copy); e = copy; } } void a() { int g = h(&g, 0, sizeof(c)); c vrsave; h(&vrsave, 33 * sizeof(c), -1); } So the warning is triggered for the cross compiler from here: $ Breakpoint 5, warning_at (location=location@entry=2147483704, opt=opt@entry=171, gmsgid=gmsgid@entry=0x15a3448 "%G%qD offset %s is out of the bounds [0, %wu] of object %qD with type %qT") at ../../gcc/diagnostic.c:1289 1289 { (gdb) bt #0 warning_at (location=location@entry=2147483704, opt=opt@entry=171, gmsgid=gmsgid@entry=0x15a3448 "%G%qD offset %s is out of the bounds [0, %wu] of object %qD with type %qT") at ../../gcc/diagnostic.c:1289 #1 0x0000000000a39dc3 in (anonymous namespace)::maybe_diag_offset_bounds (loc=2147483704, call=<gimple_call 0x7ffff6b411c8>, func=<function_decl 0x7ffff6a23500 __builtin_memcpy>, strict=<optimized out>, expr=<optimized out>, ref=...) at ../../gcc/wide-int.h:831 #2 0x0000000000a3a9d9 in (anonymous namespace)::maybe_diag_offset_bounds (ref=..., expr=<ssa_name 0x7ffff6b3dbd0>, strict=0, func=<optimized out>, call=<gimple_call 0x7ffff6b411c8>, loc=2147483704) at ../../gcc/gimple-ssa-warn-restrict.c:1586 #3 check_bounds_or_overlap (call=<gimple_call 0x7ffff6b411c8>, dst=<ssa_name 0x7ffff6b3da68>, src=<ssa_name 0x7ffff6b3dbd0>, dstsize=<optimized out>, srcsize=<optimized out>, bounds_only=<optimized out>) at ../../gcc/gimple-ssa-warn-restrict.c:1851 #4 0x0000000000a3c718 in (anonymous namespace)::wrestrict_dom_walker::check_call (this=<optimized out>, call=<gimple_call 0x7ffff6b411c8>) at ../../gcc/gimple-ssa-warn-restrict.c:1814 #5 (anonymous namespace)::wrestrict_dom_walker::before_dom_children (this=<optimized out>, bb=<optimized out>) at ../../gcc/gimple-ssa-warn-restrict.c:105 #6 0x00000000013256d8 in dom_walker::walk (this=this@entry=0x7fffffffd720, bb=<basic_block 0x7ffff6b0ab60 (4)>) at ../../gcc/domwalk.c:373 #7 0x0000000000a31c38 in (anonymous namespace)::pass_wrestrict::execute (this=<optimized out>, fun=0x7ffff6b360b0) at ../../gcc/gimple-ssa-warn-restrict.c:119 #8 0x0000000000be2885 in execute_one_pass (pass=<opt_pass* 0x1d49510 "wrestrict"(188)>) at ../../gcc/passes.c:2483 #9 0x0000000000be3008 in execute_pass_list_1 (pass=<opt_pass* 0x1d49510 "wrestrict"(188)>) at ../../gcc/passes.c:2569 #10 0x0000000000be301a in execute_pass_list_1 (pass=<opt_pass* 0x1d47020 "*all_optimizations"(-1)>) at ../../gcc/passes.c:2570 #11 0x0000000000be3059 in execute_pass_list (fn=0x7ffff6b360b0, pass=<optimized out>) at ../../gcc/passes.c:2580 #12 0x00000000008cd5cb in cgraph_node::expand (this=<cgraph_node * const 0x7ffff698f5a0 "a"/3>) at ../../gcc/context.h:48 #13 0x00000000008ce5a4 in expand_all_functions () at ../../gcc/cgraphunit.c:2334 #14 symbol_table::compile (this=0x7ffff6991000) at ../../gcc/cgraphunit.c:2685 #15 0x00000000008d0bed in symbol_table::compile (this=0x7ffff6991000) at ../../gcc/cgraphunit.c:2863 #16 symbol_table::finalize_compilation_unit (this=0x7ffff6991000) at ../../gcc/cgraphunit.c:2863 #17 0x0000000000cb9b4b in compile_file () at ../../gcc/toplev.c:481 #18 0x00000000007522c4 in do_compile () at ../../gcc/toplev.c:2176 #19 toplev::main (this=this@entry=0x7fffffffd93e, argc=<optimized out>, argc@entry=23, argv=<optimized out>, argv@entry=0x7fffffffda38) at ../../gcc/toplev.c:2311 #20 0x00000000007545db in main (argc=23, argv=0x7fffffffda38) at ../../gcc/main.c:39 For the following gimple IL: $ (gdb) p debug_gimple_stmt(call) No symbol "call" in current context. (gdb) p debug_function(cfun->decl,0) a () { void * i; void * i; int D.2622; struct c vrsave; int g; unsigned int e.0_5; void * pretmp_10; unsigned int _12; unsigned int prephitmp_13; void * pretmp_14; void * prephitmp_17; unsigned int _19; unsigned int _21; <bb 2> [local count: 1073741824]: e.0_5 = e; pretmp_10 = d; if (e.0_5 <= 15) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] <bb 3> [local count: 536870913]: _12 = 16 - e.0_5; i_15 = &g + e.0_5; __builtin_memcpy (pretmp_10, i_15, _12); e = _12; pretmp_14 = d; <bb 4> [local count: 1073741824]: # prephitmp_13 = PHI <_12(3), e.0_5(2)> # prephitmp_17 = PHI <pretmp_14(3), pretmp_10(2)> _19 = ~prephitmp_13; _21 = prephitmp_13 + 4294966768; i_22 = &vrsave + _21; __builtin_memcpy (prephitmp_17, i_22, _19); e = _19; g ={v} {CLOBBER}; vrsave ={v} {CLOBBER}; return; } I can confirm the warning is false, because the problematic __builtin_memcpy for which we trigger the warning: __builtin_memcpy (prephitmp_17, i_22, _19); and complains about i_22, but this one should be fine (with a reasonable initial value of global variable 'e'). Martin: can you please take a look?
Started with r255755.
Author: msebor Date: Thu Jan 17 22:52:47 2019 New Revision: 268048 URL: https://gcc.gnu.org/viewcvs?rev=268048&root=gcc&view=rev Log: PR middle-end/88273 - [8/9 Regression] warning: 'memcpy' offset [-527, -529] is out of the bounds [0, 16] gcc/ChangeLog: PR middle-end/88273 * gimple-ssa-warn-restrict.c (builtin_memref::extend_offset_range): Handle anti-ranges the same as no range at all. gcc/testsuite/ChangeLog: PR middle-end/88273 * gcc.dg/Warray-bounds-38.c: New test. Added: trunk/gcc/testsuite/gcc.dg/Warray-bounds-38.c Modified: trunk/gcc/ChangeLog trunk/gcc/gimple-ssa-warn-restrict.c trunk/gcc/testsuite/ChangeLog
Fixed via r268048 for GCC 9.
GCC 8.3 has been released.
Author: msebor Date: Mon Mar 18 19:44:02 2019 New Revision: 269778 URL: https://gcc.gnu.org/viewcvs?rev=269778&root=gcc&view=rev Log: Backport from mainline: PR middle-end/88273 - [8/9 Regression] warning: 'memcpy' offset [-527, -529] is out of the bounds [0, 16] gcc/ChangeLog: PR middle-end/88273 * gimple-ssa-warn-restrict.c (builtin_memref::extend_offset_range): Handle anti-ranges the same as no range at all. gcc/testsuite/ChangeLog: PR middle-end/88273 * gcc.dg/Warray-bounds-38.c: New test. Added: branches/gcc-8-branch/gcc/testsuite/gcc.dg/Warray-bounds-38.c Modified: branches/gcc-8-branch/gcc/ChangeLog branches/gcc-8-branch/gcc/gimple-ssa-warn-restrict.c branches/gcc-8-branch/gcc/testsuite/ChangeLog
Fixed in GCC 8.4 via r269778.
*** Bug 86827 has been marked as a duplicate of this bug. ***