https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78973
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|ASSIGNED |RESOLVED Resolution|--- |INVALID --- Comment #6 from Martin Sebor <msebor at gcc dot gnu.org> --- I take back what I said in comnment #4. I had misread the range information reported in the VRP dump and also debugged the wrong function (before it was inlined into the caller). I have a patch that improves the algorithm used by the warning and adds inlining context to make debugging easier. With it GCC prints the following: In file included from drivers/media/pci/ttpci/av7110.c:63:0: In function ‘irdebi’, inlined from ‘start_debi_dma’ at drivers/media/pci/ttpci/av7110.c:376:3, inlined from ‘gpioirq’ at drivers/media/pci/ttpci/av7110.c:659:3: drivers/media/pci/ttpci/av7110_hw.h:406:3: warning: ‘memcpy’: specified size between 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=] In function ‘irdebi’, inlined from ‘start_debi_dma’ at drivers/media/pci/ttpci/av7110.c:376:3, inlined from ‘gpioirq’ at drivers/media/pci/ttpci/av7110.c:668:3: drivers/media/pci/ttpci/av7110_hw.h:406:3: warning: ‘memcpy’: specified size between 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=] There are three calls to memcpy in gpioirq. The two that cause the warnings are these: <bb 94> [7.74%]: _306 = (long unsigned int) len_138; _307 = av7110_131->debi_virt; memcpy (_307, &res, _306); and <bb 109> [2.75%]: _333 = (long unsigned int) len_138; _334 = av7110_131->debi_virt; memcpy (_334, &res, _333); The range information for both of the variables is: _306: [18446744071562067968, +INF] _333: [18446744071562067968, +INF] which corresponds the warning messages. The irdebi function inlined into gpioirq looks like this: irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) { u32 res; res=av7110_debiread(av7110, config, addr, count); if (count<=4) memcpy(av7110->debi_virt, (char *) &res, count); return res; } It calls memcpy with an int argument that's less than or equal to 4 (and possibly negative). The irdebi call is inlined into start_debi_dma: void start_debi_dma(struct av7110 *av7110, int dir, unsigned long addr, unsigned int len) { ... if (len < 5) len = 5; if (dir == 1) iwdebi(av7110, 0x001e0000, addr, 0, (len + 3) & ~3); else irdebi(av7110, 0x001e0000, addr, 0, len); } I.e., with an unsigned len greater than or equal to 5 (and possibly in excess of INT_MAX). start_debi_dma is called from gpioirq like so: int len; ... av7110->debilen = irdebi(av7110, 0x000e0000, (0x4000 + 0x0F6), 0, 2); ... len = (av7110->debilen + 3) & ~3; ... case 0x04: if (!len || len > 0xff) { iwdebi(av7110, 0x000e0000, (0x4000 + 0x1FF4), 0, 2); break; } start_debi_dma(av7110, 0, (0x4000 + 0x1E00), len); len here is bounded by [INT_MIN, 0xfc], i.e., it can be negative. In summary, I think the warning is justified and the result of the signed to unsigned to signed conversions and insufficient checks for out of bounds values that don't take into consideration that the signed values can be negative.